Guide de JAXB

1. Introduction

Ceci est un article d'introduction sur JAXB (Java Architecture for XML Binding).

Tout d'abord, nous montrerons comment convertir des objets Java en XML et vice-versa, puis nous nous concentrerons sur la génération de classes Java à partir d'un schéma XML et vice-versa en utilisant le plugin JAXB-2 Maven.

2. Aperçu

JAXB fournit un moyen rapide et pratique de rassembler (écrire) des objets Java en XML et de décomposer (lire) du XML en objets. Il prend en charge un cadre de liaison qui mappe les éléments et attributs XML aux champs et propriétés Java à l'aide d'annotations Java.

Le plugin JAXB-2 Maven délègue la plupart de son travail à l'un des deux outils fournis par JDK, XJC et Schemagen.

3. Annotations JAXB

JAXB utilise des annotations Java pour augmenter les classes générées avec des informations supplémentaires. L'ajout de telles annotations à des classes Java existantes les prépare à l'exécution JAXB.

Commençons par créer un objet Java simple pour illustrer le marshalling et un-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 ci-dessus contient les annotations suivantes:

  • @XmlRootElement : le nom de l'élément XML racine est dérivé du nom de la classe et nous pouvons également spécifier le nom de l'élément racine du XML à l'aide de son attribut name
  • @XmlType : définissez l'ordre dans lequel les champs sont écrits dans le fichier XML
  • @XmlElement : définissez le nom d'élément XML réel qui sera utilisé
  • @XmlAttribute : définir le champ id est mappé comme un attribut au lieu d'un élément
  • @XmlTransient : annoter les champs que nous ne voulons pas inclure dans XML

Pour plus de détails sur l'annotation JAXB, vous pouvez consulter le lien suivant.

4. Marshalling - Conversion d'un objet Java en XML

Le marshalling fournit à une application cliente la possibilité de convertir une arborescence d'objets Java dérivée de JAXB en données XML. Par défaut, le Marshaller utilise le codage UTF-8 lors de la génération de données XML. Ensuite, nous allons générer des fichiers XML à partir d'objets Java.

Créons un programme simple en utilisant le JAXBContext qui fournit une abstraction pour gérer les informations de liaison XML / Java nécessaires pour implémenter les opérations du framework de liaison 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 fournit le point d'entrée d'un client à l'API JAXB. Par défaut, JAXB ne formate pas le document XML. Cela économise de l'espace et évite que tout espace blanc puisse être accidentellement interprété comme significatif.

Pour avoir le format JAXB de la sortie, nous définissons simplement la propriété Marshaller.JAXB_FORMATTED_OUTPUT sur true sur le Marshaller . La méthode marshal utilise un objet et un fichier de sortie où stocker le XML généré en tant que paramètres.

Lorsque nous exécutons le code ci-dessus, nous pouvons vérifier le résultat dans le book.xml pour vérifier que nous avons réussi à convertir l'objet Java en données XML:

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

5. Un-marshalling - Conversion de XML en objet Java

Le dé-marshalling fournit à une application client la possibilité de convertir des données XML en objets Java dérivés de JAXB.

Utilisons JAXB Unmarshaller pour désassembler notre book.xml en un objet Java:

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

Lorsque nous exécutons le code ci-dessus, nous pouvons vérifier la sortie de la console pour vérifier que nous avons réussi à convertir les données XML en un objet Java:

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

6. Types de données complexes

Lors de la gestion de types de données complexes qui peuvent ne pas être directement disponibles dans JAXB, nous pouvons écrire un adaptateur pour indiquer à JAXB comment gérer un type spécifique.

En utilisant XmlAdapter de JAXB , nous pouvons définir un code personnalisé pour convertir une classe non mappable en quelque chose que JAXB peut gérer. L' annotation @XmlJavaTypeAdapter utilise un adaptateur qui étend la classe XmlAdapter pour le marshaling personnalisé.

Créons un adaptateur pour spécifier un format de date lors du marshaling:

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

Nous utilisons un format de date « aaaa-MM-jj HH: mm: ss » pour convertir Date en String lors du marshalling et ThreadLocal pour rendre notre DateFormat thread-safe.

Appliquons le DateAdapter à notre livre :

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

Lorsque nous exécutons le code ci-dessus, nous pouvons vérifier le résultat dans le book.xml pour vérifier que nous avons réussi à convertir notre objet Java en XML en utilisant le nouveau format de date « aaaa-MM-jj HH: mm: ss »:

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

7. Plug-in JAXB-2 Maven

Ce plugin utilise l'API Java pour la liaison XML (JAXB), version 2+, pour générer des classes Java à partir de schémas XML (et éventuellement des fichiers de liaison) ou pour créer un schéma XML à partir d'une classe Java annotée.

Notez qu'il existe deux approches fondamentales pour créer des services Web, Contract Last et Contract First . Pour plus de détails sur ces approches, vous pouvez consulter le lien suivant.

7.1. Générer une classe Java à partir de XSD

Le plug-in JAXB-2 Maven utilise l'outil fourni par JDK XJC, un outil de compilation JAXB Binding qui génère des classes Java à partir de XSD (XML Schema Definition).

Créons un simple fichier user.xsd et utilisons le plugin JAXB-2 Maven pour générer des classes Java à partir de ce schéma XSD:

Configurons le plugin JAXB-2 Maven:

 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  

Par défaut, ce plugin localise les fichiers XSD dans src / main / xsd . Nous pouvons configurer la recherche XSD en modifiant la section de configuration de ce plugin dans le pom.xml en conséquence.

Par défaut, ces classes Java sont générées dans le dossier target / generated-resources / jaxb . Nous pouvons changer le répertoire de sortie en ajoutant un élément outputDirectory à la configuration du plugin. Nous pouvons également ajouter un élément clearOutputDir avec la valeur false pour empêcher l'effacement des fichiers de ce répertoire.

Nous pouvons également configurer une liaison JAXB globale qui remplace les règles de liaison par défaut:

Le global.xjb ci-dessus remplace le type dateTime par le type java.util.Calendar .

Lorsque nous construisons le projet, il génère des fichiers de classe dans le dossier src / main / java et le package com.baeldung.jaxb.gen .

7.2. Générer un schéma XSD à partir de 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.

Nous pouvons également enregistrer un transformSchemas , un post-processeur chargé de nommer le schéma XSD. Cela fonctionne en faisant correspondre l' espace de noms avec l'espace de noms de @XmlType de votre classe Java.

Lorsque nous construisons le projet, il génère un fichier user-gen.xsd dans le répertoire src / main / resources .

8. Conclusion

Dans cet article, nous avons couvert les concepts introductifs sur JAXB. Pour plus de détails, nous pouvons consulter la page d'accueil JAXB.

Nous pouvons trouver le code source de cet article sur GitHub.