Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
json4s-部分反序列化到案例类_Json_Scala_Jackson_Json4s - Fatal编程技术网

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

json4s-部分反序列化到案例类,json,scala,jackson,json4s,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]] = So

我有这个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
字段是字符串序列,在实际的JSON中,它是一个对象数组。当我使用以下命令反序列化并序列化它时:

implicit val formats = Serialization.formats(NoTypeHints)
val parsed = parse(data).extractOpt[Person]
val str = write( parsed )
我明白了:
{“姓名”:“柴坦尼亚”,“地址”:[]}

我有没有办法告诉json4s保持那些json对象的字符串化,而不是解析它们。我可以期望它是stingified json对象的数组:

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

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

如果您不想将它们反序列化为字符串,您可以始终将它们声明为Json

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

如果您不想将它们反序列化为字符串,您可以始终将它们声明为Json

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

只是在这里留下了一个更好的解决方案,我最终使用了它。正如@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\"}"
  ]
}

正如所料。

这里只留下一个更好的解决方案,我最终使用了它。正如@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\"}"
  ]
}
正如所料