Ho un problema nel far sì che Moxy generi "buoni" XML e JSON per un elenco di oggetti ereditati. Uno o l'altro aspetto dell'XML o il JSON sembra soddisfacente, ma non allo stesso tempo. Ecco il modello:Moxy: elenco di oggetti XML e JSON non riescono ad avere entrambi l'aspetto
public static abstract class Animal {
private String name;
protected Animal() {
}
protected Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@XmlRootElement
public static class Tiger extends Animal {
public Tiger() {
}
public Tiger(String name) {
super(name);
}
}
@XmlRootElement
public static class Lion extends Animal {
public Lion() {
}
public Lion(String name) {
super(name);
}
}
@XmlRootElement
public static class Zoo {
private List<Animal> animals = new ArrayList<>();
@XmlElementRef
public List<Animal> getAnimals() {
return animals;
}
public void setAnimals(List<Animal> animals) {
this.animals = animals;
}
public void addAnimal(Animal a) {
animals.add(a);
}
}
L'XML e JSON generato dal seguente esempio Zoo
zoo = new Zoo();
zoo.addAnimal(new Tiger("Hobbes"));
zoo.addAnimal(new Lion("Simba"));
zoo.addAnimal(new Tiger("Sherikan"));
assomigliare:
<?xml version="1.0" encoding="UTF-8"?>
<zoo>
<tiger>
<name>Hobbes</name>
</tiger>
<lion>
<name>Simba</name>
</lion>
<tiger>
<name>Sherikan</name>
</tiger>
</zoo>
{
"zoo" : {
"tiger" : [ {
"name" : "Hobbes"
}, {
"name" : "Sherikan"
} ],
"lion" : [ {
"name" : "Simba"
} ]
}
}
L'XML sembra esattamente quello che voglio anch'io, ma il JSON è strano. Il modo in cui il Moxy utilizza il tipo come chiave non conserva l'ordine tra gli elementi nell'elenco. È un bug o una funzionalità?
Se cambio l'annotazione sul Zoo.animals
al @XmlElement
l'uscita JSON guarda bene, ma l'output XML è cambiato a qualcosa che non posso usare.
{
"zoo" : {
"animals" : [ {
"type" : "tiger",
"name" : "Hobbes"
}, {
"type" : "lion",
"name" : "Simba"
}, {
"type" : "tiger",
"name" : "Sherikan"
} ]
}
}
<?xml version="1.0" encoding="UTF-8"?>
<zoo>
<animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="tiger">
<name>Hobbes</name>
</animals>
<animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="lion">
<name>Simba</name>
</animals>
<animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="tiger">
<name>Sherikan</name>
</animals>
</zoo>
L'unico modo che è venuta in mente per risolvere questo è quello di creare un file di collegamento esterna OXM di ignorare l'annotazione sul Zoo.animals
. L'associazione sottostante viene registrata utilizzando la proprietà di JAXBContextProperties.OXM_METADATA_SOURCE.
<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xml-accessor-type="PUBLIC_MEMBER" xml-accessor-order="ALPHABETICAL"
xml-mapping-metadata-complete="false"
package-name="com.example">
<java-types>
<java-type name="com.example.JAXBTest2$Zoo">
<java-attributes>
<xml-element java-attribute="animals"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
C'è una soluzione migliore a questo che non utilizza un file di bind esterno?
Blaise, grazie per la tua rapida risposta. Conoscete il motivo della memorizzazione delle informazioni sul tipo nelle chiavi JSON invece di una proprietà di tipo sintetico nell'oggetto reale? – user3099799