Sto utilizzando json4s per lavorare con oggetti JSON nel mio codice Scala. Voglio convertire i dati JSON in una rappresentazione interna. Il seguente test di apprendimento illustra il mio problema:Estrazione di tipi polimorfici in 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
}
Supponiamo che ci sia un oggetto JSON, che ha una lista di animali. Animal
è un tipo astratto e quindi non può essere istanziato. Invece, voglio analizzare la struttura JSON per restituire gli oggetti Dog
o Bird
. Hanno una firma diversa:
case class Dog(name: String) extends Animal
case class Bird(canFly: Boolean) extends Animal
Poiché la loro firma è distinta, possono essere identificate senza avere un tag di classe nell'oggetto JSON. (Per essere precisi, la struttura JSON che ricevo non fornisce quei tag).
Ho provato a serializzare un elenco di oggetti Animal (vedere il codice). Il risultato è: Ser: {"animals":[{"jsonClass":"Dog","name":"pluto"},{"jsonClass":"Bird","canFly":true}]}
Come si può vedere, durante la serializzazione, json4s aggiunge il tag di classe jsonClass
.
Come posso deserializzare un oggetto JSON che non fornisce tale tag? È possibile raggiungere questo obiettivo estendendo TypeHints
?
Ho anche trovato una domanda simile: [json4s]:Extracting Array of different objects con una soluzione che utilizza in qualche modo i generici anziché la sottoclasse. Tuttavia, se ho capito bene, questa soluzione non consente semplicemente di passare l'oggetto json e avere una rappresentazione interna. Dovrei invece selezionare il modulo che non è None
(mentre si controllano tutti i tipi possibili nella gerarchia dell'ereditarietà.Questo è un po 'noioso, dal momento che ho più classi Polimorfiche a diverse profondità nella struttura JSON
Hai mai trovare una risposta a questo? Sto affrontando la stessa sfida qui ... – borck
Purtroppo, non ho trovato una risposta.Per risolvere il problema, ho concordato con il ragazzo che ha creato il JSON serializzato per aggiungere suggerimenti tipo; ma ovviamente questa non è una soluzione se non puoi influenzare lo schema JSON. Sono ancora interessato a una risposta e ho un po 'più di conoscenza di json4s di quello che avevo al momento di scrivere la domanda, quindi cercherò di trovare una soluzione. –
@borck Grazie per aver rianimato la domanda. Ho trovato che estendere 'CustomSerializer' è una soluzione abbastanza semplice (anche se il codice per estrarre grandi strutture polimorfiche potrebbe diventare un po 'gonfio). Spero che questo ti aiuti anche a risolvere il tuo problema. –