Guida a JAXB

1. Introduzione

Questo è un articolo introduttivo su JAXB (Java Architecture for XML Binding).

Per prima cosa, mostreremo come convertire oggetti Java in XML e viceversa, quindi ci concentreremo sulla generazione di classi Java dallo schema XML e viceversa utilizzando il plug-in Maven JAXB-2.

2. Panoramica

JAXB fornisce un modo rapido e conveniente per eseguire il marshalling (scrittura) di oggetti Java in XML e annullare il marshalling (lettura) XML in oggetti. Supporta un framework di binding che mappa gli elementi e gli attributi XML su campi e proprietà Java utilizzando le annotazioni Java.

Il plugin JAXB-2 Maven delega la maggior parte del suo lavoro a uno dei due strumenti forniti da JDK XJC e Schemagen.

3. Annotazioni JAXB

JAXB utilizza le annotazioni Java per aumentare le classi generate con informazioni aggiuntive. L'aggiunta di tali annotazioni alle classi Java esistenti le prepara per il runtime JAXB.

Creiamo prima un semplice oggetto Java per illustrare il marshalling e l'annullamento del marshalling:

@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 }

La classe di cui sopra contiene le seguenti annotazioni:

  • @XmlRootElement : il nome dell'elemento radice XML è derivato dal nome della classe e possiamo anche specificare il nome dell'elemento radice dell'XML usando il suo attributo name
  • @XmlType : definisce l'ordine in cui i campi vengono scritti nel file XML
  • @XmlElement : definisce il nome dell'elemento XML effettivo che verrà utilizzato
  • @XmlAttribute : definire il campo id è mappato come un attributo invece di un elemento
  • @XmlTransient : annota i campi che non vogliamo siano inclusi in XML

Per maggiori dettagli sull'annotazione JAXB, potresti voler controllare il seguente link.

4. Marshalling - Conversione di oggetti Java in XML

Il marshalling fornisce a un'applicazione client la capacità di convertire un albero di oggetti Java derivato da JAXB in dati XML. Per impostazione predefinita, Marshaller utilizza la codifica UTF-8 durante la generazione dei dati XML. Successivamente, genereremo file XML da oggetti Java.

Creiamo un semplice programma utilizzando JAXBContext che fornisce un'astrazione per la gestione delle informazioni di binding XML / Java necessarie per implementare le operazioni di binding framework JAXB:

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")); }

La classe javax.xml.bind.JAXBContext fornisce il punto di ingresso di un client all'API JAXB. Per impostazione predefinita, JAXB non formatta il documento XML. Ciò consente di risparmiare spazio e impedisce che qualsiasi spazio bianco possa essere accidentalmente interpretato come significativo.

Per avere il formato JAXB dell'output, è sufficiente impostare la proprietà Marshaller.JAXB_FORMATTED_OUTPUT su true sul Marshaller . Il metodo marshal utilizza un oggetto e un file di output in cui memorizzare l'XML generato come parametri.

Quando eseguiamo il codice sopra, possiamo controllare il risultato nel book.xml per verificare di aver convertito correttamente l'oggetto Java in dati XML:

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

5. Un-marshalling - Conversione di XML in Java Object

L'annullamento del marshalling fornisce a un'applicazione client la capacità di convertire i dati XML in oggetti Java derivati ​​da JAXB.

Usiamo JAXB Unmarshaller per annullare il marshalling del nostro book.xml su un oggetto Java:

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

Quando eseguiamo il codice precedente, potremmo controllare l'output della console per verificare di aver convertito correttamente i dati XML in un oggetto Java:

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

6. Tipi di dati complessi

Quando si gestiscono tipi di dati complessi che potrebbero non essere direttamente disponibili in JAXB, è possibile scrivere un adattatore per indicare a JAXB come gestire un tipo specifico.

Utilizzando XmlAdapter di JAXB , possiamo definire un codice personalizzato per convertire una classe non mappabile in qualcosa che JAXB può gestire. L' annotazione @XmlJavaTypeAdapter utilizza un adattatore che estende la classe XmlAdapter per il marshalling personalizzato.

Creiamo un adattatore per specificare un formato di data durante il marshalling:

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); } }

Usiamo un formato data " aaaa-MM-gg HH: mm: ss " per convertire Date in String durante il marshalling e ThreadLocal per rendere il nostro DateFormat thread-safe.

Applichiamo il DateAdapter al nostro libro :

@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; } }

Quando eseguiamo il codice sopra, possiamo controllare il risultato nel book.xml per verificare di aver convertito con successo il nostro oggetto Java in XML utilizzando il nuovo formato di data " aaaa-MM-gg HH: mm: ss ":

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

7. Plugin Maven JAXB-2

Questo plugin utilizza l'API Java per XML Binding (JAXB), versione 2+, per generare classi Java da schemi XML (e facoltativamente file di associazione) o per creare schemi XML da una classe Java annotata.

Si noti che esistono due approcci fondamentali per la creazione di servizi Web, Ultimo contratto e Primo contratto . Per maggiori dettagli su questi approcci, potresti voler controllare il seguente collegamento.

7.1. Generazione di una classe Java da XSD

Il plug-in JAXB-2 Maven utilizza lo strumento fornito da JDK XJC, uno strumento di compilazione Binding JAXB che genera classi Java da XSD (XML Schema Definition).

Creiamo un semplice file user.xsd e utilizziamo il plug-in Maven JAXB-2 per generare classi Java da questo schema XSD:

Configuriamo il plug-in Maven JAXB-2:

 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  

Per impostazione predefinita, questo plugin individua i file XSD in src / main / xsd . Possiamo configurare la ricerca XSD modificando di conseguenza la sezione di configurazione di questo plugin nel pom.xml .

Per impostazione predefinita, queste classi Java vengono generate nella cartella target / generated-resources / jaxb . Possiamo cambiare la directory di output aggiungendo un elemento outputDirectory alla configurazione del plugin. Potremmo anche aggiungere un elemento clearOutputDir con un valore false per evitare che i file in questa directory vengano cancellati.

Possiamo anche configurare un binding JAXB globale che sovrascrive le regole di binding predefinite:

Il global.xjb precedente sostituisce il tipo dateTime al tipo java.util.Calendar .

Quando creiamo il progetto, genera i file di classe nella cartella src / main / java e nel pacchetto com.baeldung.jaxb.gen .

7.2. Generazione dello schema XSD da Java

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.

Possiamo anche registrare un transformSchemas , un post processor responsabile della denominazione dello schema XSD. Funziona facendo corrispondere lo spazio dei nomi con lo spazio dei nomi di @XmlType della classe Java.

Quando creiamo il progetto, genera un file user-gen.xsd nella directory src / main / resources .

8. Conclusione

In questo articolo, abbiamo trattato i concetti introduttivi su JAXB. Per i dettagli, possiamo dare un'occhiata alla home page di JAXB.

Possiamo trovare il codice sorgente di questo articolo su GitHub.