如何使用json4s解析json,以使原始值成为自定义案例类?

问题描述 投票:1回答:1

我想使用案例类来替换json4s中的原始类型,因为我想将业务方法放在这些案例类中。

例如:

import org.json4s.{CustomSerializer, DefaultFormats, NoTypeHints}
import org.json4s.JsonAST.{JField, JInt, JObject}
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.read

object Json4sExercise {

  trait ObjectHolder[T] {
  }

  case class IntValue(v: Int) extends ObjectHolder[Int]

  case class StringValue(v: String) extends ObjectHolder[String]

  class IntSerializer extends CustomSerializer[IntValue](format => ( {
    case JInt(x) => IntValue(x.toInt)
  }, {
    case IntValue(x) => JInt(BigInt(x))
  }
  ))

  implicit val formats =  Serialization.formats(NoTypeHints) + new IntSerializer

  def main(args: Array[String]): Unit = {
    println(read[Map[String, _]](""" {"price":350} """))
  }

}

但不是我想要的:Map(price-> IntValue(x:350)),它打印了Map(price-> 350)

scala json4s
1个回答
0
投票

为了提高安全性和效率,请考虑改用jsoniter-scala

只需将依赖项添加到您的build.sbt

libraryDependencies ++= Seq(
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core"   % "2.0.1",
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "2.0.1" % Provided // required only in compile-time
)

并使用以下代码中所示的自定义编解码器:

trait ObjectHolder[T]

case class IntValue(v: Int) extends ObjectHolder[Int]
object IntValue {
  implicit val codec: JsonValueCodec[IntValue] = new JsonValueCodec[IntValue] {
    override def decodeValue(in: JsonReader, default:  IntValue): IntValue =
      new IntValue(in.readInt())
    override def encodeValue(x: IntValue, out: JsonWriter): Unit = 
      out.writeVal(x.v)
    override val nullValue: IntValue = new IntValue(0)
  }
}

case class StringValue(v: String) extends ObjectHolder[String]
object StringValue {
  implicit val codec: JsonValueCodec[StringValue] = new JsonValueCodec[StringValue] {
    override def decodeValue(in: JsonReader, default:  StringValue): StringValue =
      new StringValue(in.readString(default.v))
    override def encodeValue(x: StringValue, out: JsonWriter): Unit = 
      out.writeVal(x.v)
    override val nullValue: StringValue = new StringValue(null)
  }
}

case class Response(price: IntValue)
object Response {
  implicit val codec: JsonValueCodec[Response] = JsonCodecMaker.make(CodecMakerConfig)
}

val response = readFromArray[Response]("""{"price":350}""".getBytes("UTF-8"))
val json = writeToArray(Response(price = IntValue(350)))

println(response)
println(new String(json, "UTF-8"))

它应该打印:

Response(IntValue(350))
{"price":350}
© www.soinside.com 2019 - 2024. All rights reserved.