json4s - 部分反序列化为案例类

时间:2018-05-04 19:14:12

标签: json scala jackson json4s

我有这个JSON对象

{
  "name": "Chaitanya",
  "addresses": [
    { "street": "20 ABC", "apt": "10" },
    { "street": "10 XYZ", "apt": "D3" }
  ]
}

我正在尝试将其反序列化为以下案例类:

case class Person(
    name: Option[String] = None,
    addresses: Option[Seq[String]] = Some(Seq.empty)
)
上面case类中的

addresses字段是String的序列,而在实际的JSON中,它是一个对象数组。当我使用:

反序列化并序列化它时
implicit val formats = Serialization.formats(NoTypeHints)
val parsed = parse(data).extractOpt[Person]
val str = write( parsed )

我明白了: { "name":"Chaitanya", "addresses":[] }

有什么方法可以告诉json4s保持这些json对象的字符串化而不是解析它们。我可以期待它是一个stingified json对象的数组:

{
  "name": "Chaitanya",
  "addresses": [
    "{\"street\":\"20 ABC\",\"apt\":\"10\"}",
    "{\"street\":\"10 XYZ\",\"apt\":\"D3\"}"
  ]
}

我有什么方法可以使用自定义序列化程序或类型提示吗?

2 个答案:

答案 0 :(得分:2)

如果您不希望将它们反序列化为字符串,则可以将它们声明为Json

case class Person(
    name: Option[String] = None,
    addresses: Option[Json/JsArray/JsObject/JsWhatever] =     Some(Seq.empty)
)

答案 1 :(得分:0)

在这里留下一个更好的解决方案,我最终使用了它。正如@ shane-delmore所提到的,您可以使用Json / JsArray / JsObject / JsWhatever摆脱困境。如果您不想在案例类定义中使用任何特定于JSON4S的类型,则可以创建自定义序列化器:

// Serializer
// Converts JObject to stringified JSON blob
val serializer: PartialFunction[JValue, String] = {
  case jObj: JObject =>
    implicit val formats = Serialization.formats(NoTypeHints)
    write(jObj)
}

// Deserializer
// Converts String into JString
val deserializer: PartialFunction[Any, JValue] = {
  case x: String => JString(x)
}


class JSONBlobSerializer extends CustomSerializer[String]( _ => (
 serializer,
 deserializer
))

使用上述自定义序列化程序,您可以使JSON部分保持字符串化

implicit val formats = Serialization.formats(NoTypeHints) + new JSONBlobSerializer()
write( parse( data ).extract[Person] )

导致:

{
  "name": "Chaitanya",
  "addresses": [
    "{\"street\":\"20 ABC\",\"apt\":\"10\"}",
    "{\"street\":\"10 XYZ\",\"apt\":\"D3\"}"
  ]
}

符合预期。

相关问题