JAXB 2.x : Wie überschreiben eines XmlElement-annotation von übergeordneten Klasse - Mission Impossible?
Warum ist das nicht möglich? Es scheint so einfach, aber es verhält sich nicht wie erwartet.
Zusammenfassung: Klasse A mit einer aggregierten DataA bean in der Erwägung, dass die Klasse B (eine Unterklasse der Klasse A) ist mit einer aggregierten Datenb bean (während Datenb erstreckt DataA).
Schrieb ich diesen test-Klassen zu visualisieren und zu erklären, meine Frage:
Klasse A:
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name="root")
public class A {
private DataA source = new DataA();
@XmlElement(name="source")
public DataA getSource() {
return source;
}
public void setSource(DataA source) {
this.source = source;
}
}
und seine DataA Klasse (ich habe das FELD annotation, so dass alle Felder bekommt marshalled):
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@XmlAccessorType(XmlAccessType.FIELD)
public class DataA {
public String string1 = "1";
public String string2 = "2";
}
Und nun die Klasse B (Unterklasse der Klasse A): Mein Ziel ist es, die Wiederverwendung von Funktionalitäten von Ein-und auch wieder die Eigenschaften aus der DataA bean mit der Datenb bean:
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name="root")
public class B extends A {
private DataB source = new DataB();
public DataB getSource() {
return this.source;
}
public void setSource(DataB source) {
this.source = source;
}
}
Seine entsprechenden Datenb bean sieht wie folgt aus:
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@XmlAccessorType(XmlAccessType.FIELD)
public class DataB extends DataA {
public String string3 = "3";
}
Nun, wenn ich marshall eine Instanz der Klasse A, es gibt diese Ausgabe:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<source>
<string1>1</string1>
<string2>2</string2>
</source>
</root>
Wenn ich marshall eine Instanz der Klasse B, erhalte ich das gleiche Ergebnis:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<source>
<string1>1</string1>
<string2>2</string2>
</source>
</root>
Aber ich erwartet, dass auch string3 bekommen würde gemarshallt, aber es ist nur das schreiben der Eigenschaften der bean-DataA! WARUM? Diese ist nicht wirklich intuitiv, wenn das denken in Bezug auf OOP.
Wenn ich die @XmlElement-annotation auch auf die Klasse-B - ... so wie hier:
@XmlElement
public DataB getSource() {
return this.source;
}
... dann die Eigenschaft wird vorgebracht zweimal, denn es ist einmal kommentiert von den Eltern der Klasse, als auch von der Kind-Klasse. Das ist auch das, was ich nicht will:
Die Ausgabe ist jetzt:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<source xsi:type="dataB" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<string1>1</string1>
<string2>2</string2>
<string3>3</string3>
</source>
<source>
<string1>1</string1>
<string2>2</string2>
<string3>3</string3>
</source>
</root>
Was ich erwartet habe von JAXB als Ergebnis ist das folgende XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<source>
<string1>1</string1>
<string2>2</string2>
<string3>3</string3>
</source>
</root>
Irgendwelche Tipps, wie Sie Sie optimieren JAXB zu produzieren das erwartete Ergebnis??
Vielen Dank für jede Rückmeldung.
- versuchen Sie
@XMLElement
über Felder eher als öffentliche Methode - helfen tut es nicht. Ich habe auch versucht XmlAccessType.FELD ohne XmlElement-annotation auf den Feldern, und ich habe auch versucht XmlAccessType.EIGENSCHAFT ohne XmlElement-annotation auf die GETTER... ist das ein bug? wie diese ist es nicht wirklich nützlich.
- ... und wie man sehen kann, lege ich die annotation @XmlAccessorType(XmlAccessType."NONE") für beide Klassen... also nur diejenigen Elemente, die kommentiert von XmlElement-Objekten erhalten gemarshallt
- Dies wurde behoben in der JRE Stamm: java.net/jira/browse/JAXB-804
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einfach nicht, kommentieren Sie die source-Eigenschaft, Klasse B. Die source-Eigenschaft zugeordnet ist, die auf der übergeordneten Klasse und sollten nicht zugeordnet werden, wieder auf die Kind-Klasse. Da Sie kommentieren die get - /set-Methoden, die entsprechende get/set aufgerufen sein, Klasse B.
UPDATE
Kann es ein bug in der U-JAXB (Referenz-Implementierung). Wenn ich diesen starte, aktualisiert Beispiel mit EclipseLink JAXB (MOXy) ich bekomme die folgende Ausgabe:
Dieser reproduziert werden kann, mit dem folgenden code:
Verwenden MOXy als die JAXB-Implementierung, die Sie brauchen, um liefern eine Datei mit jaxb.Eigenschaften in das Modell-package (test) mit den folgenden Eintrag:
These set methods can be different on the parent and child as long as they are named the same.
Du meinst ObjektMethod
mit der spiegelung ?brauchen Sie nicht zu verwenden MOXy..
Ändern Sie einfach die Klasse B und die Verwendung von @XmlAlso.
ENDLICH SCHREIBEN:
Vielen Dank Blaise für all diese Hinweise. MOXy jetzt arbeitet gut mit meinem realen Anwendung mit echten Bohnen. schön!
Der einzige Nachteil den ich derzeit habe ist, dass die Letzte Zeile in dieser Konfiguration wird der code nicht mehr funktioniert, weil MOXy verwendet natürlich einen anderen namespace-Präfix-mapping-Mechanismus.
Hast du einen pointer dazu? Ich suchte die MOXy-Dokumentation und Suche nach namespace, aber nichts ähnliches gefunden.
Können Sie diese Methode verwenden:
diese Zuordnung für mich gearbeitet.