Gids voor JAXB

1. Inleiding

Dit is een inleidend artikel over JAXB (Java Architecture for XML Binding).

Eerst laten we zien hoe Java-objecten naar XML kunnen worden geconverteerd en vice versa, en vervolgens zullen we ons concentreren op het genereren van Java-klassen op basis van XML-schema en vice versa met behulp van de JAXB-2 Maven-plug-in.

2. Overzicht

JAXB biedt een snelle en gemakkelijke manier om Java-objecten in XML te rangschikken (schrijven) en XML in objecten te ontkoppelen (lezen). Het ondersteunt een bindend raamwerk dat XML-elementen en attributen toewijst aan Java-velden en -eigenschappen met behulp van Java-annotaties.

De JAXB-2 Maven-plug-in delegeert het grootste deel van zijn werk aan een van de twee door JDK geleverde tools XJC en Schemagen.

3. JAXB-annotaties

JAXB gebruikt Java-annotaties om de gegenereerde klassen uit te breiden met aanvullende informatie. Door dergelijke annotaties aan bestaande Java-klassen toe te voegen, worden ze voorbereid op de JAXB-runtime.

Laten we eerst een eenvoudig Java-object maken om rangschikking en ont-rangschikking te illustreren:

@XmlRootElement (naam = "boek") @XmlType (propOrder = {"id", "naam", "datum"}) openbare klasse Boek {privé Lange id; private String naam; private String-auteur; privé Datum datum; @XmlAttribute public void setId (lange id) {this.id = id; } @XmlElement (name = "title") public void setName (String naam) {this.name = naam; } @XmlTransient public void setAuthor (String auteur) {this.author = author; } // constructor, getters en setters}

De bovenstaande klasse hierboven bevat de volgende annotaties:

  • @XmlRootElement: de naam van het root-XML-element is afgeleid van de klassenaam en we kunnen ook de naam van het root-element van de XML specificeren met behulp van het name-attribuut
  • @XmlType: definieer de volgorde waarin de velden in het XML-bestand worden geschreven
  • @XmlElement: definieer de eigenlijke XML-elementnaam die zal worden gebruikt
  • @XmlAttribute: definieer het id-veld wordt toegewezen als een attribuut in plaats van een element
  • @XmlTransient: annoteer velden die we niet in XML willen opnemen

Voor meer details over JAXB-annotatie, wil je misschien de volgende link bekijken.

4. Marshalling - Java-object converteren naar XML

Marshalling biedt een clienttoepassing de mogelijkheid om een ​​van JAXB afgeleide Java-objectboom in XML-gegevens om te zetten. Standaard is het Marshaller gebruikt UTF-8-codering bij het genereren van XML-gegevens. Vervolgens zullen we XML-bestanden genereren van Java-objecten.

Laten we een eenvoudig programma maken met de JAXBContext die een abstractie biedt voor het beheren van de XML / Java-bindende informatie die nodig is om de JAXB-bindende raamwerkbewerkingen te implementeren:

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

De javax.xml.bind.JAXBContext class biedt het toegangspunt van een klant tot JAXB API. Standaard formatteert JAXB het XML-document niet. Dit bespaart ruimte en voorkomt dat witruimte per ongeluk als significant wordt geïnterpreteerd.

Om de uitvoer in JAXB te laten formatteren, stellen we eenvoudig de Marshaller.JAXB_FORMATTED_OUTPUT eigendom aan waar op de Marshaller. De marshal-methode gebruikt een object en een uitvoerbestand waarin de gegenereerde XML als parameters wordt opgeslagen.

Wanneer we de bovenstaande code uitvoeren, kunnen we het resultaat in de book.xml om te verifiëren dat we met succes Java-objecten in XML-gegevens hebben omgezet:

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

5. Un-marshalling - XML ​​naar Java-object converteren

Un-marshalling biedt een clienttoepassing de mogelijkheid om XML-gegevens om te zetten in JAXB-afgeleide Java-objecten.

Laten we JAXB gebruiken Unmarshaller om onze te ontmantelen book.xml terug naar een Java-object:

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

Wanneer we de bovenstaande code uitvoeren, kunnen we de console-uitvoer controleren om te verifiëren dat we XML-gegevens met succes hebben geconverteerd naar een Java-object:

Boek [id = 1, naam = Boek1, auteur = null, datum = za 12 nov 11:38:18 ICT 2016]

6. Complexe gegevenstypen

Bij het verwerken van complexe gegevenstypen die mogelijk niet direct beschikbaar zijn in JAXB, kunnen we een adapter schrijven om JAXB aan te geven hoe een specifiek type moet worden beheerd.

Met behulp van JAXB's XmlAdapter, kunnen we een aangepaste code definiëren om een ​​niet-toepasbare klasse om te zetten in iets dat JAXB aankan. De @XmlJavaTypeAdapter annotatie gebruikt een adapter die de extensie XmlAdapter klasse voor aangepaste marshaling.

Laten we een adapter maken om een ​​datumnotatie op te geven bij het rangschikken:

openbare klasse DateAdapter breidt XmlAdapter uit {privé statische laatste ThreadLocal dateFormat = nieuwe ThreadLocal () {@Override beschermd DateFormat initialValue () {retourneer nieuwe SimpleDateFormat ("jjjj-MM-dd HH: mm: ss"); }}; @Override public Date unmarshal (String v) genereert Uitzondering {return dateFormat.get (). Parse (v); } @Override public String marshal (Datum v) gooit Uitzondering {return dateFormat.get (). Format (v); }}

We gebruiken een datumnotatie 'jjjj-MM-dd UU: mm: ss" bekeren Datum naar Draad bij het rangschikken en ThreadLocal om onze te maken Datumnotatie draad-veilig.

Laten we de DatumAdapter naar onze Boek:

@XmlRootElement (naam = "boek") @XmlType (propOrder = {"id", "naam", "datum"}) openbare klasse Boek {privé Lange id; private String naam; private String-auteur; privé Datum datum; @XmlAttribute public void setId (lange id) {this.id = id; } @XmlTransient public void setAuthor (String auteur) {this.author = author; } @XmlElement (name = "title") public void setName (String naam) {this.name = naam; } @XmlJavaTypeAdapter (DateAdapter.class) public void setDate (Date date) {this.date = date; }}

Wanneer we de bovenstaande code uitvoeren, kunnen we het resultaat in de book.xml om te verifiëren dat we ons Java-object met succes hebben geconverteerd naar XML met de nieuwe datumnotatie "jjjj-MM-dd UU: mm: ss“:

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

7. JAXB-2 Maven-plug-in

Deze plug-in gebruikt de Java API voor XML Binding (JAXB), versie 2+, om Java-klassen te genereren op basis van XML-schema's (en optioneel bindende bestanden) of om XML-schema te maken op basis van een geannoteerde Java-klasse.

Merk op dat er twee fundamentele benaderingen zijn voor het bouwen van webservices, Contract laatste en Contract eerst. Raadpleeg de volgende link voor meer informatie over deze benaderingen.

7.1. Een Java-klasse genereren op basis van XSD

De JAXB-2 Maven-plug-in gebruikt de door JDK geleverde tool XJC, een JAXB Binding-compilertool die Java-klassen genereert op basis van XSD (XML Schema Definition).

Laten we een eenvoudig maken gebruiker.xsd bestand en gebruik de JAXB-2 Maven-plug-in om Java-klassen te genereren op basis van dit XSD-schema:

Laten we de JAXB-2 Maven-plug-in configureren:

 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 

Standaard lokaliseert deze plug-in XSD-bestanden in src / main / xsd. We kunnen XSD-lookup configureren door het configuratiegedeelte van deze plug-in in het pom.xml overeenkomstig.

Deze Java-klassen worden standaard gegenereerd in het target / gegenereerde-resources / jaxb map. We kunnen de uitvoermap wijzigen door een outputDirectory element toe aan de plugin-configuratie. We kunnen ook een clearOutputDir element met de waarde false om te voorkomen dat de bestanden in deze directory worden gewist.

We kunnen ook een globale JAXB-binding configureren die de standaardbindingsregels overschrijft:

De global.xjb hierboven overschrijft de datum Tijd typ naar het java.util.Calendar type.

Wanneer we het project bouwen, genereert het klassebestanden in de src / main / java map en pakket com.baeldung.jaxb.gen.

7.2. XSD-schema genereren vanuit Java

Dezelfde plug-in gebruikt de door JDK geleverde tool Schemagen. Dit is een JAXB Binding-compilertool die een XSD-schema uit Java-klassen kan genereren. Om ervoor te zorgen dat een Java-klasse in aanmerking komt voor een XSD-schemakandidaat, moet de klasse worden geannoteerd met een @XmlType annotatie.

We hergebruiken de Java-klassebestanden uit het vorige voorbeeld. Laten we de plug-in configureren:

 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 

JAXB scant standaard alle mappen onder src / main / java recursief voor geannoteerde JAXB-klassen. We kunnen een andere specificeren bron map voor onze JAXB geannoteerde klassen door een bron element toe aan de plug-in configuratie.

We kunnen ook een transformSchemas, een postprocessor die verantwoordelijk is voor het benoemen van het XSD-schema. Het werkt door de naamruimte met de naamruimte van de @XmlType van uw Java-klasse.

Wanneer we het project bouwen, genereert het een user-gen.xsd bestand in het src / main / resources directory.

8. Conclusie

In dit artikel hebben we inleidende concepten over JAXB behandeld. Voor details kunnen we een kijkje nemen op de homepage van JAXB.

We kunnen de broncode voor dit artikel vinden op GitHub.