Anleitung zu JAXB

1. Einleitung

Dies ist ein Einführungsartikel zu JAXB (Java Architecture for XML Binding).

Zuerst zeigen wir, wie Java-Objekte in XML konvertiert werden und umgekehrt, und dann konzentrieren wir uns darauf, Java-Klassen aus dem XML-Schema zu generieren und umgekehrt, indem wir das JAXB-2 Maven-Plugin verwenden.

2. Übersicht

JAXB bietet eine schnelle und bequeme Möglichkeit, Java-Objekte in XML zu marshallen (schreiben) und XML in Objekte zu marshallen (lesen). Es unterstützt ein Bindungsframework, das XML-Elemente und -Attribute mithilfe von Java-Anmerkungen Java-Feldern und -Eigenschaften zuordnet.

Das JAXB-2 Maven-Plugin delegiert den größten Teil seiner Arbeit an eines der beiden von JDK bereitgestellten Tools XJC und Schemagen.

3. JAXB-Anmerkungen

JAXB verwendet Java-Annotationen, um die generierten Klassen um zusätzliche Informationen zu erweitern. Das Hinzufügen solcher Anmerkungen zu vorhandenen Java-Klassen bereitet sie auf die JAXB-Laufzeit vor.

Lassen Sie uns zunächst ein einfaches Java-Objekt erstellen, um das Marshalling und das Nicht-Marshalling zu veranschaulichen:

@XmlRootElement(name = "book") @XmlType(propOrder = { "id", "name", "date" }) public class Book { private Long id; private String name; private String author; private Date date; @XmlAttribute public void setId(Long id) { this.id = id; } @XmlElement(name = "title") public void setName(String name) { this.name = name; } @XmlTransient public void setAuthor(String author) { this.author = author; } // constructor, getters and setters }

Die obige Klasse enthält die folgenden Anmerkungen:

  • @XmlRootElement : Der Name des XML- Stammelements wird vom Klassennamen abgeleitet, und wir können den Namen des Stammelements des XML auch mithilfe seines Namensattributs angeben
  • @XmlType : Definiert die Reihenfolge, in der die Felder in die XML-Datei geschrieben werden
  • @XmlElement : Definiert den tatsächlichen XML-Elementnamen, der verwendet wird
  • @XmlAttribute : Definieren Sie, dass das ID-Feld als Attribut anstelle eines Elements zugeordnet wird
  • @XmlTransient : Kommentieren Sie Felder, die nicht in XML aufgenommen werden sollen

Weitere Informationen zur JAXB-Annotation finden Sie unter folgendem Link.

4. Marshalling - Konvertieren von Java-Objekten in XML

Marshalling bietet einer Clientanwendung die Möglichkeit, einen von JAXB abgeleiteten Java-Objektbaum in XML-Daten zu konvertieren. Standardmäßig verwendet der Marshaller beim Generieren von XML-Daten die UTF-8-Codierung. Als Nächstes generieren wir XML-Dateien aus Java-Objekten.

Erstellen wir ein einfaches Programm mit dem JAXBContext , das eine Abstraktion zum Verwalten der XML / Java-Bindungsinformationen bereitstellt, die zum Implementieren der JAXB-Bindungsframework-Operationen erforderlich sind:

public void marshal() throws JAXBException, IOException { Book book = new Book(); book.setId(1L); book.setName("Book1"); book.setAuthor("Author1"); book.setDate(new Date()); JAXBContext context = JAXBContext.newInstance(Book.class); Marshaller mar= context.createMarshaller(); mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); mar.marshal(book, new File("./book.xml")); }

Die Klasse javax.xml.bind.JAXBContext bietet den Einstiegspunkt eines Clients für die JAXB-API. Standardmäßig formatiert JAXB das XML-Dokument nicht. Dies spart Platz und verhindert, dass Leerzeichen versehentlich als signifikant interpretiert werden.

Um die Ausgabe im JAXB-Format zu formatieren, setzen wir einfach die Marshaller.JAXB_FORMATTED_OUTPUT- Eigenschaft auf dem Marshaller auf true . Die Marshall-Methode verwendet ein Objekt und eine Ausgabedatei, in der das generierte XML als Parameter gespeichert wird.

Wenn wir den obigen Code ausführen , überprüfen wir möglicherweise das Ergebnis in der Datei book.xml , um sicherzustellen , dass das Java-Objekt erfolgreich in XML-Daten konvertiert wurde:

  Book1 2016-11-12T11:25:12.227+07:00 

5. Un-Marshalling - Konvertieren von XML in Java-Objekte

Durch das Aufheben der Marshalling-Funktion kann eine Clientanwendung XML-Daten in von JAXB abgeleitete Java-Objekte konvertieren.

Verwenden wir JAXB Unmarshaller, um unsere book.xml wieder in ein Java-Objekt zu entfernen :

public Book unmarshall() throws JAXBException, IOException { JAXBContext context = JAXBContext.newInstance(Book.class); return (Book) context.createUnmarshaller() .unmarshal(new FileReader("./book.xml")); }

Wenn wir den obigen Code ausführen, überprüfen wir möglicherweise die Konsolenausgabe, um sicherzustellen, dass wir XML-Daten erfolgreich in ein Java-Objekt konvertiert haben:

Book [id=1, name=Book1, author=null, date=Sat Nov 12 11:38:18 ICT 2016]

6. Komplexe Datentypen

Bei der Verarbeitung komplexer Datentypen, die in JAXB möglicherweise nicht direkt verfügbar sind, schreiben wir möglicherweise einen Adapter, der JAXB angibt, wie ein bestimmter Typ verwaltet werden soll.

Mit dem XmlAdapter von JAXB können wir einen benutzerdefinierten Code definieren, um eine nicht zuordnungsfähige Klasse in etwas zu konvertieren, das JAXB verarbeiten kann. Die Annotation @XmlJavaTypeAdapter verwendet einen Adapter, der die XmlAdapter- Klasse für benutzerdefiniertes Marshalling erweitert.

Erstellen wir einen Adapter, um beim Marshalling ein Datumsformat anzugeben:

public class DateAdapter extends XmlAdapter { private static final ThreadLocal dateFormat = new ThreadLocal() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; @Override public Date unmarshal(String v) throws Exception { return dateFormat.get().parse(v); } @Override public String marshal(Date v) throws Exception { return dateFormat.get().format(v); } }

Wir verwenden das Datumsformat „ JJJJ-MM-TT HH: MM: SS “, um das Datum beim Marshalling in String zu konvertieren , und ThreadLocal , um unser DateFormat threadsicher zu machen .

Wenden wir den DateAdapter auf unser Buch an :

@XmlRootElement(name = "book") @XmlType(propOrder = { "id", "name", "date" }) public class Book { private Long id; private String name; private String author; private Date date; @XmlAttribute public void setId(Long id) { this.id = id; } @XmlTransient public void setAuthor(String author) { this.author = author; } @XmlElement(name = "title") public void setName(String name) { this.name = name; } @XmlJavaTypeAdapter(DateAdapter.class) public void setDate(Date date) { this.date = date; } }

Wenn wir den obigen Code ausführen , überprüfen wir möglicherweise das Ergebnis in der Datei book.xml , um sicherzustellen , dass wir unser Java-Objekt mit dem neuen Datumsformat „ JJJJ-MM-TT HH: MM: SS “ erfolgreich in XML konvertiert haben :

  Book1 2016-11-10 23:44:18final 

7. JAXB-2 Maven Plugin

Dieses Plugin verwendet die Java-API für XML-Bindung (JAXB), Version 2+, um Java-Klassen aus XML-Schemas (und optional Bindungsdateien) zu generieren oder um ein XML-Schema aus einer mit Anmerkungen versehenen Java-Klasse zu erstellen.

Beachten Sie, dass es zwei grundlegende Ansätze zum Erstellen von Webdiensten gibt: Vertrag zuletzt und Vertrag zuerst . Weitere Informationen zu diesen Ansätzen finden Sie unter folgendem Link.

7.1. Generieren einer Java-Klasse aus XSD

Das JAXB-2 Maven-Plugin verwendet das von JDK bereitgestellte Tool XJC, ein JAXB Binding-Compiler-Tool, das Java-Klassen aus XSD (XML Schema Definition) generiert.

Erstellen wir eine einfache user.xsd- Datei und verwenden das JAXB-2 Maven-Plugin, um Java-Klassen aus diesem XSD-Schema zu generieren:

Konfigurieren wir das JAXB-2 Maven Plugin:

 org.codehaus.mojo jaxb2-maven-plugin 2.3   xjc  xjc      src/main/resources/global.xjb   src/main/resources/user.xsd  ${basedir}/src/main/java false  

Standardmäßig findet dieses Plugin XSD-Dateien in src / main / xsd . Wir können die XSD-Suche konfigurieren, indem wir den Konfigurationsabschnitt dieses Plugins in der Datei pom.xml entsprechend ändern .

Standardmäßig werden diese Java-Klassen im Ordner target / generate-resources / jaxb generiert . Wir können das Ausgabeverzeichnis ändern, indem wir der Plugin-Konfiguration ein outputDirectory- Element hinzufügen . Wir können auch ein clearOutputDir- Element mit dem Wert false hinzufügen , um zu verhindern, dass die Dateien in diesem Verzeichnis gelöscht werden.

Wir können auch eine globale JAXB-Bindung konfigurieren, die die Standardbindungsregeln überschreibt:

Die obige Datei global.xjb überschreibt den Typ dateTime mit dem Typ java.util.Calendar .

Wenn wir das Projekt erstellen, werden Klassendateien im Ordner src / main / java und im Paket com.baeldung.jaxb.gen generiert .

7.2. XSD-Schema aus Java generieren

The same plugin uses the JDK-supplied tool Schemagen. This is a JAXB Binding compiler tool that can generate an XSD schema from Java classes. In order for a Java Class to be eligible for an XSD schema candidate, the class must be annotated with a @XmlType annotation.

We reuse the Java class files from the previous example. Let's configure the plugin:

 org.codehaus.mojo jaxb2-maven-plugin 2.3   schemagen  schemagen      src/main/java/com/baeldung/jaxb/gen  src/main/resources false   /jaxb/gen user user-gen.xsd    

By default, JAXB scans all the folders under src/main/java recursively for annotated JAXB classes. We may specify a different source folder for our JAXB annotated classes by adding a source element to the plug-in configuration.

Wir können auch transformSchemas registrieren, einen Postprozessor , der für die Benennung des XSD-Schemas verantwortlich ist. Es funktioniert, indem der Namespace mit dem Namespace des @XmlType Ihrer Java-Klasse abgeglichen wird .

Wenn wir das Projekt erstellen, generiert es eine Datei user-gen.xsd im Verzeichnis src / main / resources .

8. Fazit

In diesem Artikel haben wir einführende Konzepte zu JAXB behandelt. Einzelheiten finden Sie auf der JAXB-Homepage.

Den Quellcode für diesen Artikel finden Sie auf GitHub.