Mam problem z pobieraniem Moxy do generowania "dobrego" XML i JSON dla listy dziedziczonych obiektów. Każdy z XML wygląda find lub JSON wygląda dobrze, ale nie w tym samym czasie. Oto model:Moxy: Lista obiektów XML i JSON nie mogą wyglądać dobrze
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);
}
}
XML i JSON wygenerowana z instancji Zoo
zoo = new Zoo();
zoo.addAnimal(new Tiger("Hobbes"));
zoo.addAnimal(new Lion("Simba"));
zoo.addAnimal(new Tiger("Sherikan"));
wyglądać następująco:
<?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"
} ]
}
}
XML wygląda dokładnie to, co chcę go też, ale JSON jest dziwny. Sposób, w jaki Moxy wykorzystuje typ jako klucz, nie zachowuje porządku wśród elementów na liście. Czy to błąd lub funkcja?
Jeśli zmienię adnotację na Zoo.animals
na @XmlElement
, wynik JSON wygląda dobrze, ale wynik XML zmienił się na coś, czego nie mogę użyć.
{
"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>
Jedynym sposobem mam wymyślić, aby rozwiązać ten jest utworzenie zewnętrznego wiążącego plik OXM aby przesłonić adnotacji na Zoo.animals
. Powiązanie poniżej jest rejestrowane przy użyciu właściwości 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>
Czy istnieje lepsze rozwiązanie tego, że nie używa zewnętrznego pliku wiążącego?
Blaise, dziękuję za szybką odpowiedź. Czy znasz przyczynę przechowywania informacji o typie w kluczach json zamiast właściwości typu syntetycznego w rzeczywistym obiekcie? – user3099799