json4s - частично десериализовать в класс case - PullRequest
0 голосов
/ 04 мая 2018

У меня есть этот объект 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)
)
Поле

addresses в приведенном выше классе case является последовательностью 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 голосов
/ 02 августа 2018

Просто оставляю лучшее решение, которое я в итоге использовал. Как уже упоминалось @ shane-delmore, вы можете использовать Json / JsArray / JsObject / JsWh независимо от того, что вы делаете. Если вы не хотите использовать какие-либо особые типы 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\"}"
  ]
}

Как и ожидалось.

0 голосов
/ 04 мая 2018

Если вы не хотите, чтобы они десериализовались в строку, вы всегда можете объявить их как Json

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