Я использую json4s для работы с объектами JSON в моем коде Scala. Я хочу преобразовать данные JSON во внутреннее представление. Следующий учебный тест иллюстрирует мою проблему:Извлечение полиморфных типов в json4s
"Polimorphic deserailization" should "be possible" in {
import org.json4s.jackson.Serialization.write
val json =
"""
|{"animals": [{
| "name": "Pluto"
| }]
|}
""".stripMargin
implicit val format = Serialization.formats(ShortTypeHints(List(classOf[Dog], classOf[Bird])))
val animals = parse(json) \ "animals"
val ser = write(Animals(Dog("pluto") :: Bird(canFly = true) :: Nil))
System.out.println(ser)
// animals.extract[Animal] shouldBe Dog("Pluto") // Does not deserialize, because Animal cannot be constructed
}
Предположим, что есть объект JSON, который имеет список животных. Animal
- абстрактный тип и, следовательно, не может быть создан. Вместо этого я хочу проанализировать структуру JSON, чтобы вернуть объекты Dog
или Bird
. Они имеют разные подписи:
case class Dog(name: String) extends Animal
case class Bird(canFly: Boolean) extends Animal
Потому что их подписи различны, они могут быть идентифицированы без класса тегов в объекте JSON. (Точнее, структура JSON, которую я получаю, не предоставляет эти теги).
Я попытался сериализовать список объектов Animal (см. Код). Результат: Ser: {"animals":[{"jsonClass":"Dog","name":"pluto"},{"jsonClass":"Bird","canFly":true}]}
Как вы можете видеть, при сериализации json4s добавляет тег class jsonClass
.
Как можно десериализовать объект JSON, который не предоставляет такой тег? Можно ли достичь этого, расширив TypeHints
?
Мне также понравился аналогичный вопрос: [json4s]:Extracting Array of different objects с решением, которое каким-то образом использует дженерики вместо подкласса. Однако, если я правильно понимаю, это решение не позволяет просто передать объект json и иметь внутреннее представление. Вместо этого мне нужно будет выбрать форму, которая не является None
(при проверке всех возможных типов в наследовании hiearchy. Это немного утомительно, так как у меня есть несколько полиморфных классов на разных глубинах в структуре JSON.
ли вы когда-нибудь найти ответ на этот вопрос? Я столкнулся с такой же проблемой здесь ... – borck
К сожалению, я не нашел ответа.В качестве обходного пути я согласился с парнем, который создал сериализованный JSON, чтобы добавить подсказки типов; но это, очевидно, не решение, если вы не можете повлиять на схему JSON. Я по-прежнему интересуюсь ответом и имею немного больше знаний о json4s, чем у меня на момент написания вопроса, поэтому я постараюсь придумать решение. –
@borck Спасибо за оживление вопроса. Я обнаружил, что расширение «CustomSerializer» является довольно простым решением (хотя код для извлечения больших полиморфных структур может немного раздуваться). Я надеюсь, что это также поможет вам решить вашу проблему. –