无法使用 json4s 序列化可选值 class 实例
Trouble serializing optional value class instances with json4s
我正在尝试使用 json4s 将带有可选值-class 字段的案例 class 序列化为 JSON。到目前为止,我无法正确呈现可选的 value-class 字段(请参阅下面的示例片段)。
我尝试了 json-native
和 json-jackson
库,结果是相同的。
这是一个简短的独立测试
import org.json4s.DefaultFormats
import org.scalatest.FunSuite
import org.json4s.native.Serialization._
class JsonConversionsTest extends FunSuite {
implicit val jsonFormats = DefaultFormats
test("optional value-class instance conversion") {
val json = writePretty(Foo(Option(Id(123)), "foo-name", Option("foo-opt"), Id(321)))
val actual =
"""
|{
| "id":{
| "value":123
| },
| "name":"foo-name",
| "optField":"foo-opt",
| "nonOptId":321
|}
|""".stripMargin.trim
assert(json === actual)
val correct =
"""
|{
| "id": 123,
| "name":"foo-name",
| "optField":"foo-opt",
| "nonOptId":321
|}
|""".stripMargin.trim
assert(json !== correct)
}
}
case class Id(value: Int) extends AnyVal
case class Foo(id: Option[Id], name: String, optField: Option[String], nonOptId: Id)
我正在使用 scala 2.12 和最新的 json4s-native
版本:
"org.json4s" %% "json4s-native" % "3.6.7"
它看起来与 this 问题非常相似,似乎没有修复或评论。
自定义序列化程序可以节省您的时间。
object IdSerializer extends CustomSerializer[Id] ( format => (
{ case JInt(a) => Id(a.toInt) },
{ case a: Id => JInt(a.value) }
))
implicit val formats = DefaultFormats + IdSerializer
val json = writePretty(Foo(Option(Id(123)), "foo-name", Option("foo-opt"), Id(321)))
在任何情况下尝试其他选项,例如使用 jsoniter-scala instead. It is much safe and efficient 而不是 json4s,尤其是在美化 JSON.
的序列化中
Add/replace 依赖关系:
libraryDependencies ++= Seq(
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "0.55.2" % Compile,
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "0.55.2" % Provided // required only in compile-time
)
推导出顶层数据结构的编解码器,并用它序列化成字符串:
import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._
case class Id(value: Int) extends AnyVal
case class Foo(id: Option[Id], name: String, optField: Option[String], nonOptId: Id)
implicit val codec: JsonValueCodec[Foo] = JsonCodecMaker.make(CodecMakerConfig())
val json = writeToString(Foo(Option(Id(123)), "foo-name", Option("foo-opt"), Id(321)), WriterConfig(indentionStep = 2))
val correct =
"""{
| "id": 123,
| "name": "foo-name",
| "optField": "foo-opt",
| "nonOptId": 321
|}""".stripMargin
assert(json == correct)
还有更有效的选项可以立即存储到字节数组,java.nio.ByteBuffer 或 java.io.OutputStream。
我正在尝试使用 json4s 将带有可选值-class 字段的案例 class 序列化为 JSON。到目前为止,我无法正确呈现可选的 value-class 字段(请参阅下面的示例片段)。
我尝试了 json-native
和 json-jackson
库,结果是相同的。
这是一个简短的独立测试
import org.json4s.DefaultFormats
import org.scalatest.FunSuite
import org.json4s.native.Serialization._
class JsonConversionsTest extends FunSuite {
implicit val jsonFormats = DefaultFormats
test("optional value-class instance conversion") {
val json = writePretty(Foo(Option(Id(123)), "foo-name", Option("foo-opt"), Id(321)))
val actual =
"""
|{
| "id":{
| "value":123
| },
| "name":"foo-name",
| "optField":"foo-opt",
| "nonOptId":321
|}
|""".stripMargin.trim
assert(json === actual)
val correct =
"""
|{
| "id": 123,
| "name":"foo-name",
| "optField":"foo-opt",
| "nonOptId":321
|}
|""".stripMargin.trim
assert(json !== correct)
}
}
case class Id(value: Int) extends AnyVal
case class Foo(id: Option[Id], name: String, optField: Option[String], nonOptId: Id)
我正在使用 scala 2.12 和最新的 json4s-native
版本:
"org.json4s" %% "json4s-native" % "3.6.7"
它看起来与 this 问题非常相似,似乎没有修复或评论。
自定义序列化程序可以节省您的时间。
object IdSerializer extends CustomSerializer[Id] ( format => (
{ case JInt(a) => Id(a.toInt) },
{ case a: Id => JInt(a.value) }
))
implicit val formats = DefaultFormats + IdSerializer
val json = writePretty(Foo(Option(Id(123)), "foo-name", Option("foo-opt"), Id(321)))
在任何情况下尝试其他选项,例如使用 jsoniter-scala instead. It is much safe and efficient 而不是 json4s,尤其是在美化 JSON.
的序列化中Add/replace 依赖关系:
libraryDependencies ++= Seq(
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % "0.55.2" % Compile,
"com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "0.55.2" % Provided // required only in compile-time
)
推导出顶层数据结构的编解码器,并用它序列化成字符串:
import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._
case class Id(value: Int) extends AnyVal
case class Foo(id: Option[Id], name: String, optField: Option[String], nonOptId: Id)
implicit val codec: JsonValueCodec[Foo] = JsonCodecMaker.make(CodecMakerConfig())
val json = writeToString(Foo(Option(Id(123)), "foo-name", Option("foo-opt"), Id(321)), WriterConfig(indentionStep = 2))
val correct =
"""{
| "id": 123,
| "name": "foo-name",
| "optField": "foo-opt",
| "nonOptId": 321
|}""".stripMargin
assert(json == correct)
还有更有效的选项可以立即存储到字节数组,java.nio.ByteBuffer 或 java.io.OutputStream。