Ich habe ein bestehendes Datenmodell. Ich möchte dieses Datenmodell in XML ausdrücken.
Es sieht so aus, als hätte ich zwei Möglichkeiten, JAXB zu benutzen:
Ich sehe Vorteile und Nachteile beider Ansätze. Es scheint, dass die meisten Leute, die JAXB verwenden, mit der XSD-Datei beginnen. Es macht Sinn, dass der XSD die Goldstandard-Wahrheit sein sollte, da er das Datenmodell auf eine wirklich plattformübergreifende Weise ausdrückt.
Ich bin geneigt, zuerst mit dem XSD zu beginnen, aber es scheint eklig, dass ich eine separate Mapping-Klasse schreiben und pflegen muss, die Daten zwischen meiner Welt und der JAXB-Welt pendelt.
Irgendwelche Empfehlungen?
Die Generierung der XSD aus den vorhandenen Klassen klingt für mich wie der sicherste Weg.
Wie auch immer, wenn Sie JAXB nicht gut kennen, dann könnte der Ansatz, Ihre eigenen Klassen zu kommentieren, äußerst frustrierend sein (sowohl in puncto Schmerz als auch in der Zeit :)).
Dies ist mir in einem verwandten Kontext passiert, als ich versuchte, Superklassen von JAXB generierten Klassen manuell zu extrahieren und dann die Instanzen in XML zu marshallen. Ich bekam verschiedene (kryptische) JAXB-Ausnahmen. Richtig, mein JAXB-Wissen ist noch nicht so tief.
Wenn Sie darauf bestehen, JAXB zu verwenden, schlage ich vor, den ersten Ansatz (XSD + XJC) zu verwenden, um erste JAXB-Anmerkungen für Ihre Klassen zu erhalten.
Sie können XSD + XJC verwenden, um eine Idee zu erhalten, wie Sie Ihre eigenen Klassen mit Anmerkungen versehen können. Dann können Sie versuchen, die richtigen Anmerkungen auf sie zu passen. Beginne mit den komplexeren Klassen (Referenzen, Vererbung, Referenzenliste, Referenzliste zur abstrakten Basisklasse) schon früh.
Die Verwendung einer anderen Technologie zum Generieren von XSD aus nicht annotierten Klassen als Kick-Start auf dem XSD kann hilfreich sein. Oder du entscheidest dich für eine XSD, die den Großteil deiner Klasseninhalte abdeckt.
Wenn die Absicht dieser Bemühung darin besteht, die Instanzen auch in XML zu marshallen, dann schlage ich vor, auf JAXBElement zu achten. In einigen Fällen (die ich aufgrund fehlender Kenntnisse nicht anweisen kann), werden Instanzen nur dann marshallen, wenn sie in ein JAXBElement eingebunden sind.
Wir verwenden HyperJAXB, um basierend auf einer Gruppe von XSDs eine Persistenzschicht zu generieren. Die generierten Klassen werden auch zum Marshalling verwendet. Wir haben viel Spaß damit, dies zu machen, vor allem. wegen IDREFs und JAXBElement.
Lesen zwischen den Zeilen, ich glaube, das folgende ist wahr:
Dieses Szenario wird normalerweise als "meet in the middle" -Mapping bezeichnet. Es wird nur teilweise von JAXB gelöst. Zum Glück, da JAXB eine Spezifikation ist, gibt es andere Implementierungen wie EclipseLink JAXB (MOXy), die Sie verwenden können.
MOXy bietet eine XPath-basierte Mapping-Erweiterung, mit der Sie zwischen dem Java-Modell und dem gewünschten XML-Schema mappen können:
Sie können xjc verwenden und haben immer noch nur eine Klasse mit XML-Anmerkungen, die als Datenobjekt dienen. Aber das ist für den Fall, dass Sie die Klassen nicht auf jeder gebauten neu generieren.
Und da Code-Generierung meiner Meinung nach in der Frage ist, wo ich anfangen soll, schlage ich vor, mit dem Unterricht anzufangen. Wenn Sie Ihre Klassen als Ausgangspunkt haben, müssen Sie diese Klassen nie erneut generieren. Und mit der Zeit beginnen Ihre Klassen mit zu wachsen - einschließlich @XmlTransient
, Vererbung, Hilfsmethoden und anderen (JPA) Annotationen.
Sie sind so ziemlich am schlechtesten Ausgangspunkt für JAXB. In Ihrer Position denke ich, JiBX könnte eine bessere Wette sein, es kann Schema aus einem nicht annotierten Klassenmodell generieren und dann binden XML zurück zum Objektmodell zur Laufzeit, ohne Annotationen zu verwenden.
Die Lösung, mit der wir fortgefahren sind, besteht darin, ein separates Projekt zu haben, das alle Datenmodelle enthält, die durch XML-Schemas definiert sind, aus denen Java-Klassen mit Hilfe von JAXB abgeleitet werden. Andere Projekte, die die Datenmodelle verwenden, hängen von diesem Schemapaket ab.
Auf diese Weise werden alle "Verträge" zwischen den Projekten an einem einzigen Ort unter Verwendung der netten portablen xsd-Repräsentation definiert. Es sind keine Mapping-Klassen erforderlich, da wir nur die JAXB-generierten direkt verwenden.