json4s - Частичная десериализация в класс дела

У меня есть этот объект JSON

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

Который я пытаюсь десериализовать в следующий класс case:

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\"}"
  ]
}

Есть ли способ сделать это с помощью настраиваемого сериализатора или подсказки типа?


person Chaitanya Chandurkar    schedule 04.05.2018    source источник


Ответы (2)


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

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

Просто оставил здесь лучшее решение, которое я в конечном итоге использовал. Как упоминал @ 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\"}"
  ]
}

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

person Chaitanya Chandurkar    schedule 02.08.2018