使用jsoniter-scala 是使用Scala 最简单、最有效的方法。
添加依赖:
libraryDependencies ++= Seq(
// Use the %%% operator instead of %% for Scala.js
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "2.12.0",
// Use the "provided" scope instead when the "compile-internal" scope is not supported
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "2.12.0" % "compile-internal"
)
使用来自这个 sn-p 的自定义编解码器:
import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._
object Example01 {
sealed trait Message
case class Deepest(someNum: Int)
case class Inner(superDeep: Deepest)
case class Outer(aValue: Int, aNestedValue: Inner) extends Message
implicit val innerCodec: JsonValueCodec[Inner] = new JsonValueCodec[Inner] {
private val codec: JsonValueCodec[Inner] = JsonCodecMaker.make
override def decodeValue(in: JsonReader, default: Inner): Inner =
readFromStringReentrant(in.readString(null))(codec)
override def encodeValue(x: Inner, out: JsonWriter): Unit =
out.writeVal(writeToStringReentrant(x)(codec))
override def nullValue: Inner = null
}
implicit val messageCodec: JsonValueCodec[Message] =
JsonCodecMaker.make(CodecMakerConfig.withDiscriminatorFieldName(None))
def main(args: Array[String]): Unit = {
val message = readFromString[Message](
"""{
| "Outer": {
| "aValue": 5,
| "aNestedValue": "{ \"superDeep\": { \"someNum\": 1 } }"
| }
|}""".stripMargin)
println(writeToString[Message](message, WriterConfig.withIndentionStep(4)))
}
}
预期输出:
{
"Outer": {
"aValue": 5,
"aNestedValue": "{\"superDeep\":{\"someNum\":1}}"
}
}
如果应该对多个类型进行字符串化,您可以定义一个函数,该函数采用常规编解码器并返回一个编解码器,该编解码器将原始类型的输出字符串化:
def makeStringifyingCodec[A](codec: JsonValueCodec[A]): JsonValueCodec[A] =
new JsonValueCodec[A] {
override def decodeValue(in: JsonReader, default: A): A =
readFromStringReentrant(in.readString(null))(codec)
override def encodeValue(x: A, out: JsonWriter): Unit =
out.writeVal(writeToStringReentrant(x)(codec))
override def nullValue: A = null.asInstanceOf[A]
}
并将其用于Outer 类的字段类型:
implicit val innerCodec: JsonValueCodec[Inner] =
makeStringifyingCodec(JsonCodecMaker.make[Inner])
implicit val messageCodec: JsonValueCodec[Message] =
JsonCodecMaker.make(CodecMakerConfig.withDiscriminatorFieldName(None))