Die Java Architecture for XML Binding (JAXB) in der Praxis

XML leicht gemacht

Andreas Holubek, Frank Ulbricht

Die Nutzung von XML-Dokumenten für die verschiedensten Aufgabengebiete gehört inzwischen zum festen Standard unter Java. Aufgrund der vielen Vorteile eines solchen Datenformates wurden einige Nachteile bei der Entwicklung in Kauf genommen. So wird vor allem das Lesen, Verändern und Schreiben immer wieder zu einem zeitaufwendigen Programmier-Problem. Die Java Architecture for XML Binding (JAXB) soll hier eine Lösung bieten.

Architektur

Als erstes fällt sicherlich der integrierte Parser auf. Für die Nutzung von JAXB wird kein externer Parser benötigt, wie er zum Beispiel durch das JAXP Framework zur Verfügung gestellt wird. Der Grund dafür ist leicht zu finden. Die generierten Klassen wissen um die Zusammensetzung des Datenstroms. Mit diesen Informationen ist der Pars-Prozess schneller als die SAX Variante. Durch den bekannten Aufbau der Objekte wiederum wird viel Overhead aus der DOM Variante einfach weggelassen. Zusammengefasst erzeugt der im JAXB enthaltene Compiler speziell angepassten, sehr schnellen Quelltext, um ganz spezielle XML-Dateien zu Lesen und zu Schreiben.
Ausgangspunkt der Entwicklung ist der Document Type Descriptor (DTD). Aus diesem wird mittels eines durch JAXB bereitgestellten Compilers (XJC) eine Menge von abhängigen Klassen und Hilfsmethoden erzeugt. Mit Hilfe der generierten Klassen ist wiederum die Wandlung von und nach XML möglich. Hierbei wird der Übergang vom XML-Dokument zum Objektbaum als unmarshalling und der Übergang von den Objekten zu XML als marshalling bezeichnet. Abpictureung 1 verdeutlicht die prinzipiellen Zusammenhänge.

Abb.1: Zusammenhänge in der JAXB Architektur

Die primären Komponenten der Architektur lassen sich wie folgt beschreiben:

  • Schema Compiler: Der Schema Compiler transformiert oder bindet ein Ausgangsschema an eine Menge von abhängigen Klassen. Innerhalb von JAXB EA1 wird hierzu die DTD von XML 1.0 genutzt.
  • Binding Framework: Stellt ein Framework von öffentlichen Klassen und Interfaces dar, auf welchem die vom Schema Compiler erzeugten Klassen aufbauen. Die vom Binding Framework bereitgestellten Klassen implementieren die grundlegenden Operationen, wie marshalling, unmarshalling und die Validierung von Datenströmen.

Binding Language: Die Binding Language ist eine XML-basierte Beschreibungssprache, welche die Abpictureung eines Schemas auf eine Menge von Klassen spezifiziert. Innerhalb der JAXB-Implementierung können erweiterte Eigenschaften an die Klassen weitergegeben werden. Wie im Praxisbeispiel zu sehen, ist die Beschreibung nicht zwingend notwendig, jedoch sehr zu empfehlen. Aus der Spezifikation von JAXB kann die genaue DTD der Binding Language entnommen werden.

Die Spezifikationen sowie die Referenzimplementierung werden unter dem Java Specification Request JSR-31 (XML Data Binding) zusammengefasst.

Zur Praxis: Mapping und Klassen erstellen

Um in die Praxis einzusteigen, wird als erstes eine JAXB-Implementierung benötigt. Diese kann zum Beispiel von Sun bezogen werden [1]. Zu beachten ist, dass die derzeitige Lösung noch eine Early Access Version darstellt, weshalb mit dem einen oder anderen Problem in jedem Fall gerechnet werden muss.
Wie schon beschrieben, kann man sich JAXB als ein Framework zum Mapping zwischen XML-Schemas und Java-Klassen vorstellen. Aus einem vorhandenen Schema werden automatisch die Quelltexte für die Java-Klassen erzeugt. Basis dafür ist die entsprechende DTD-Datei (Document Type Descriptor).
In unserem Beispiel gehen wir von einer DTD Datei aus, welche ein Buch beschreibt (siehe auch book.dtd):

Book.java
Chapter.java
Content.java

Mit obigem Beispiel haben wir gleichzeitig die Minimalvariante genutzt. Im Fall des Elementes content zum Beispiel kann man jetzt natürlich überlegen, ob es tatsächlich als eigene Klasse modelliert werden soll oder ob es ein Attribut der Klasse Chapter ist. Genau so stellt sich natürlich die Frage nach der Package-Bezeichnung.
Zum besseren Handling empfehlen sich einige Anpassungen. Grundsätzlich werden diese Anpassungen in einer weiteren XML-Datei mit der Endung xjs hinterlegt. Sind keine Informationen vorhanden, werden Standards, wie im vorherigen Beispiel demonstriert, angenommen. Eine zusätzliche Beschreibungsdatei könnte folgenden Inhalt haben (siehe auch book.xjs):

Es gibt noch weitere interessante Features für die Generierung der Klassen, so können zum Beispiel auch Konstruktoren definiert werden, die bereits Initialisierungswerte übernehmen können. Auch lassen sich Interfaces erstellen, die zum Beispiel von mehreren Klassen, die alternativ auftreten können, automatisch implementiert werden (z.B.: ). Leider sind in der vorliegenden Version diese Features zum Teil noch nicht ganz ausgereift oder nur teilweise implementiert.

Jetzt können die Klassen mit Hilfe des von uns definierten Mappings erzeugt werden. Auch hier kann wieder der schon bekannte XJC Compiler verwendet werden:

OutputStream os = new FileOutputStream("book.xml");
book.validate();
book.marshal(os);
os.close();

Nach der Ausführung sollte eine Datei book.xml mit dem durch die Objekte definierten Inhalt entstanden sein.
Das Lesen erfolgt ebenfalls über einen beliebigen Java Stream. Von JAXB wird eine statische Methode (unmarshal) in der Root Klasse dafür zur Verfügung gestellt:

InputStream is = new FileInputStream("book.xml");
Book book = Book.unmarshal(is);
is.close();

[1] http://java.sun.com/xml/jaxb/index.html – Java Architecture for XML Binding

Geschrieben von
Andreas Holubek, Frank Ulbricht
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.