JAXB Marshalling rein von Schnittstellen

9

Ich habe eine komplexe Hierarchie von Java-Interfaces, die ich mit JAXB marshalen (und nicht unbedingt unmarshalen) möchte. Diese Schnittstellen stellen Objekte dar, die von einer JAX-RS-REST-API als XML, JSON, YAML usw. zurückgegeben werden (ich verwende RestEasy, das JAXB-annotierte Typen in anderen Formaten als XML marshallen kann).

Das Problem scheint zu sein, dass JAXB grundsätzlich klassenorientiert ist. Ich habe viele Web-Recherchen über die Schwierigkeiten mit JAXB und Schnittstellen durchgeführt, wobei die nächstliegenden Lösungen MOXy JAXB - Schnittstellen zu XML und JAXB und Interface Fronted Models . Ich habe jedoch zwei Hauptprobleme: a) Ich möchte Anmerkungen machen / in Bezug auf Schnittstellen arbeiten, nicht die konkreten Klassen (von denen es mehrere Implementierungen gibt und signifikante andere Zustände enthält, die nicht gemarshallt werden sollten), und b) ich habe mehrere Ebenen der Schnittstellenvererbung. Hier ist ein Beispiel für die Schnittstellen, abzüglich aller JAXB-Annotationen:

%Vor%

Im Idealfall würde dies wie folgt aussehen:

%Vor%

Dies führt, abstrakt ausgedrückt, zu Problemen wie der Bestimmung der am weitesten abgeleiteten annotierten Schnittstelle, von denen theoretisch mehr als eine sein könnte. In meinem Fall jedoch glaube ich, dass die konkreten Klassen nur eine einzige Schnittstelle implementieren, die gemarsaled werden sollte. Unmarshalling ist nicht notwendig, da ich separate Klassen habe, die Upsert-Eigenschaften definieren.

Also meine Frage ist, ist das überhaupt möglich mit JAXB zu umgehen, und wenn ja, wie? Auch wenn ich bei der Definition von Bindings, Adaptern usw. sehr explizit sein muss, würde ich gerne im JAXB-Framework arbeiten, um die Vorteile aller Nicht-XML-Anbieter in RestEasy zu nutzen.

    
Trevor Robinson 06.03.2012, 18:33
quelle

2 Antworten

0

Ich denke, die Antwort ist, dass JAXB überhaupt nicht dazu gedacht ist, dies zu unterstützen, und dass es dumm ist, es zu erzwingen. Auch das JAXB-gesteuerte JSON-Marshalling erweist sich als nicht ideal.

Ich habe mein eigenes Marshalling-Framework mit eigenen Anmerkungen geschrieben:

%Vor%

Die generierten Marshaller schreiben in eine Abstraktionsschicht (derzeit für JSON und XML implementiert). Das gibt viel mehr Flexibilität, um die Ausgabe für verschiedene Darstellungen ohne eine Menge an Anmerkungen und Adaptern natürlich zu machen. Z. B., was ich Keyed-Object-Maps anrufe, wobei jedes Objekt seinen Map-Key enthält. In JSON möchten Sie eine Karte, aber in XML möchten Sie eine Sequenz:

%Vor%

Sieht so aus, als ob sich auch 4 andere Leute darum kümmern, also hoffentlich kann ich sie irgendwann öffnen. : -)

    
Trevor Robinson 10.04.2012, 16:53
quelle
1

Kurze Antwort: Verwenden Sie @XmlElement(type = Object.class) in Ihrem Schnittstellenfeld.

Details unten:

Ich habe zwei Möglichkeiten gefunden, wie Sie JAXB Ihre Schnittstellen serialisieren können:

  1. @XmlAnyElement
  2. @XmlElement(type = Object.class)

1. @ XmlAnyElement

Beschriften Sie einfach Ihr Interface-Typ-Feld mit @XmlAnyElement und JAXB serialisiert die Schnittstelle von ihrem konkreten Typ. Vergessen Sie nicht, die konkreten Typen mit @XmlRootElement zu kommentieren und die konkreten Typen dem JAXBContext hinzuzufügen. Das vollständige Beispiel folgt:

%Vor%

Ausgabe XML:

%Vor%

Die Nachteile dieser Methode:

  • Sie können nicht jedes einzelne Feld von Ihrem Pojo von XML unterscheiden (gleiche Implementierungen werden mit demselben Tag geschrieben)
  • Sie haben keine Art von Informationen zu Unmarshall Ihre XML (wenn Sie dies wünschen)

Diese Nachteile werden in der zweiten Lösung behoben:

2. @ XmlElement (type = Objekt.class)

Ich bin darüber im Blogeintrag von mikesir87 gestolpert. Ersetzen Sie einfach die @XmlAnyElement Annotationen von oben durch @XmlElement(type = Object.class) Sie sollten so etwas in der Pojo-Klasse von oben haben:

%Vor%

Wiederholen Sie unser Beispiel, das resultierende XML:

%Vor%

Dies kann auch deserialisiert werden:

%Vor%

Ergebnisausgabe:

%Vor%

Wahrscheinlich eine " hackish " Lösung, aber sie erledigt die Aufgabe.

    
alexsvecencu 19.01.2017 08:11
quelle

Tags und Links