I am using json4s to work with JSON objects in my Scala code. I want to convert JSON data to an internal representation. The following learning test illustrates my problem:
"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
}
Suppose there is a JSON object which has a list of Animals. Animal
is an abstract type, and hence cannot be instantiated. Instead, I want to parse the JSON structure to return either Dog
or Bird
objects. They have a different signature:
case class Dog(name: String) extends Animal
case class Bird(canFly: Boolean) extends Animal
Because their signature is distinct, they can be identified without having a class Tag in the JSON object. (To be precise, the JSON structure I receive does not provide those tags).
I tried to serialize a list of Animal objects (see the code). The result is: Ser: {"animals":[{"jsonClass":"Dog","name":"pluto"},{"jsonClass":"Bird","canFly":true}]}
As you can see, when serializing, json4s adds the class-tag jsonClass
.
How can I deserialize a JSON object that does not provide such a tag? Is it possible to achieve this by extending TypeHints
?
I also found a similar question: [json4s]:Extracting Array of different objects with a solution that somehow uses generics instead of subclassing. However, if I understand correctly, this solution does not allow to simply pass the json object and have an internal representation. Instead I would need to select the form that is not None
(while checking all possible Types in the inheritance hiearchy. This is a bit tedious, since I have multiple Polymorphic classes at different depths in the JSON structure.