JAXB qui est l'acronyme de l'anglais « Java API for XML Binding » est une boîte à outils pour sérialisation et désérialisation d'objets java. Elle permet de voyager de manière bidirectionnelle entre les univers Java et XML grâce à un mapping (XML <-> Java). Ce mapping est flexible dans la mesure il peut être généré directement par JAXB à partir d'un schéma XML ou simplement définie par le développeur lui-même via des annotations.
Dans ce document je vais indiquer comment générer des classes java à partir d'un schéma XML puis comment aller d'un fichier XML à un objet Java et vice versa.

JAXB permet de réaliser 3 types d'échanges entre les univers XML et Java :
Pour rendre ce document digeste, je vais parcourir les API de JAXB à travers l'exemple d'un magasin de location de DVD et VHS. A chaque article loué j'associe :
Consultez ce fichier rentals.xml listant les locations en cours :
<?xml version="1.0" encoding="UTF-8"?> <rentals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="rentals.xsd" xmlns="http://dotmyself.net/j2xml"> <rental type="DVD"> <user>1</user> <title>Casino Royal</title> <begindate>15/07/2007</begindate> </rental> <rental type="VHS"> <user>3</user> <title>Borat</title> <begindate>16/07/2007</begindate> </rental> </rentals>
Voici le schéma XML rentals.xsd utilisé par le magasin de location :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema targetNamespace="http://dotmyself.net/j2xml" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://dotmyself.net/j2xml"> <xs:element name="begindate" type="xs:string"/> <xs:element name="rental"> <xs:complexType> <xs:sequence> <xs:element ref="user"/> <xs:element ref="title"/> <xs:element ref="begindate"/> </xs:sequence> <xs:attribute name="type" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="DVD"/> <xs:enumeration value="VHS"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="rentals"> <xs:complexType> <xs:sequence> <xs:element ref="rental" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="title" type="xs:string"/> <xs:element name="user" type="xs:int"/> </xs:schema>
Pour générer les classes java, utilisez le compilateur xjc comme suite :
Quelques explications :
Vous pouvez modifier les classes produites pour les adapter plus finement à vos besoins. Néanmoins, si vous avez le choix, je vous conseille :
Ci-dessous la classe XML2Java.java pourvue d'une méthode main. Cette classe instancie un Unmarshaller depuis le JAXBContext puis l'utilise pour lire le fichier rentals.xml et produire des objets java :
/**
* @author Hyacinthe MENIET
* Created on 15 juil. 07
*/
package net.dotmyself.j2xml;
import java.io.FileReader;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
/**
* Unmarshalles the given XML Document.
*/
public class XML2Java {
/**
* The main method.
* @param args the path to file to read.
* @throws Exception
*/
public static void main(String[] args) throws Exception {
if(args == null || args.length < 1) {
throw new IllegalArgumentException("You must indicate a path to file to read");
}
String fileName = args[0];
// Unmarshalles the given XML file to objects
JAXBContext context;
context = JAXBContext.newInstance("net.dotmyself.j2xml");
Unmarshaller unmarshaller = context.createUnmarshaller();
Rentals rentals = (Rentals) unmarshaller.unmarshal(new FileReader(fileName));
List<Rental> listOfRentals = rentals.getRental();
// Displays objects
for(Rental rental : listOfRentals){
System.out.println("Type="+rental.getType()+", "
+"User="+rental.getUser()+", "
+"Title="+rental.getTitle()+", "
+"Begin date="+rental.getBegindate());
}
}
}
Après compilation, le résultat de l'exécution :
Ci-dessous je créé la classe Java2XML.java pourvue d'une méthode main. Cette classe instancie des objets de type Rental et Rentals à partir de l'ObjectFactory et dans lesquels elle stocke des données statiques. Puis grâce au Marshaller elle produit un fichier XML :
/**
* @author Hyacinthe MENIET
* Created on 15 juil. 07
*/
package net.dotmyself.j2xml;
import java.io.FileWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
/**
* Marshalles the created java Objects to the specified XML Document.
*/
public class Java2XML {
/**
* The main method.
* @param args the path to file to generate.
* @throws Exception
*/
public static void main(String[] args) throws Exception {
if(args == null || args.length < 1) {
throw new IllegalArgumentException("You must indicate a path to file to generate");
}
String fileName = args[0];
// Instanciates an ObjectFactory
ObjectFactory objFactory = new ObjectFactory();
// Creates first rental
Rental rental1 = objFactory.createRental();
rental1.setBegindate("15/07/2007");
rental1.setTitle("Casino Royal");
rental1.setType("DVD");
rental1.setUser(1);
// Creates second rental
Rental rental2 = objFactory.createRental();
rental2.setBegindate("16/07/2007");
rental2.setTitle("Borat");
rental2.setType("VHS");
rental2.setUser(3);
// Stores rentals
Rentals rentals = objFactory.createRentals();
rentals.getRental().add(rental1);
rentals.getRental().add(rental2);
// Marshalles objects to the specified file
JAXBContext context = JAXBContext.newInstance(Rentals.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(rentals, new FileWriter(fileName));
}
}
Après compilation, l'exécution :
Ce qui génère le fichier generated-rentals.xml.