Aide mémoire : la (dé)sérialisation XML en Java avec jaxb

Aide mémoire (Développement) / Uncategorized
Petit aide mémoire pour la (dé)sérialisation XML en Java avec JAXB.

1. Les annotations
2. Conversion java –> XML
3. Conversion XML –> java
4. Exemple
5. Sources

1. Les annotations

Pour pouvoir convertir des objets Java en XML (ou réciproquement), il suffit juste d’ajouter des annotations sur la classe à convertir.

Ces annotations font parties du package javax.xml.bind.annotation qui est inclus dans la JRE.

Les annotations suivantes peuvent être mise sur la classe:

  • @XmlRootElement : définit le nom (name) du tag XML a utiliser. On peut également préciser le namespace
  • @XmlType : définit l’ordre d’écriture des éléments (propOrder), mais aussi d’autres trucs que j’ai pas encore utilisé
  • @XmlAccessorType : permet de choisir où seront posé les annotations des éléments de la classe : les getter/setter (XmlAccessType.PROPERTY), les attributs (XmlAccessType.FIELD) ou autre.

Suivant la valeur passé à @XmlAccessorType, vous pouvez rajoutez les annotations suivantes sur les éléments de la classe (par défaut, il faudra les mettre sur les getters) :

  • @XmlAttribute : ajoute un attribut au tag définit par @XmlRootElement, on peut définir le nom (name), la présence (required) et le namespace
  • @XmlElement : ajoute un sous tag à celui définit par @XmlRootElement, on peut définir le nom (name), la présence (required), la valeur par défaut (defaultValue) le type, le namespace et nillable
  • @XmlElementWrapper : dans le cas d’une liste, permet d’englober les éléments de la liste, on peut définir le nom (name), la présence (required), le namespace et nillable

2. Conversion java –> XML

Pour convertir un objet java annoté en XML :

    JAXBContext context = JAXBContext.newInstance(T.class);
    Marshaller m = context.createMarshaller();
    m.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    m.marshal (object2convert, outputStream);


T doit être la classe à convertir, object2convert une instance de T. La variable outputStream doit être un flux sortant (System.out, File, etc. ).

3. Conversion XML –> java

Pour convertir un XML en objet java :

    JAXBContext context = JAXBContext.newInstance(T.class);
    Unmarshaller um = context.createUnmarshaller();
    T object2convert = (T) um.unmarshal(inputStream);


T doit être la classe à convertir, object2convert une instance de T. La variable inputStream doit être un flux entrant (System.in, FileReader, etc. ).

4. Exemple

import javax.xml.bind.annotation.XmlAccessType ;
import javax.xml.bind.annotation.XmlAccessorType ;
import javax.xml.bind.annotation.XmlAttribute ;
import javax.xml.bind.annotation.XmlRootElement ;
import javax.xml.bind.annotation.XmlType ;

@XmlRootElement(name = "book")
@XmlType(propOrder = {"author", "name", "publisher", "isbn"})
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Book {

    private String name;
    private String author;
    private String publisher;
    private String isbn;

    @XmlAttribute(name = "title")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlAttribute(name = "author")
    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @XmlAttribute(name = "publisher")
    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    @XmlAttribute(name = "isbn")
    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
}

import java.util.ArrayList ;
import javax.xml.bind.annotation.XmlAccessType ;
import javax.xml.bind.annotation.XmlAccessorType ;
import javax.xml.bind.annotation.XmlAttribute ;
import javax.xml.bind.annotation.XmlElement ;
import javax.xml.bind.annotation.XmlElementWrapper ;
import javax.xml.bind.annotation.XmlRootElement ;

@XmlRootElement(name = "bookstore")
@XmlAccessorType(XmlAccessType.FIELD)
public class Bookstore {

    @XmlElementWrapper(name = "bookList")
    @XmlElement(name = "book")
    private ArrayList bookList;
    @XmlAttribute(name = "name")
    private String name;
    @XmlAttribute(name = "location")
    private String location;

    public void setBookList(ArrayList bookList) {
        this.bookList = bookList;
    }

    public ArrayList getBooksList() {
        return bookList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}

Ce qui donne une fois passé dans la moulinette pour convertir en XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookstore location="Frankfurt Airport" name="Fraport Bookstore">
	<bookList>
		<book isbn="978-0060554736" publisher="Harpercollins" title="The Game" author="Neil Strauss"/>
		<book isbn="978-3832180577" publisher="Dumont Buchverlag" title="Feuchtgebiete" author="Charlotte Roche"/>
	</bookList>
</bookstore>

Sans la présence de l’annotation @XmlElementWrapper, vous obtiendrez :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookstore location="Frankfurt Airport" name="Fraport Bookstore">
	<book isbn="978-0060554736" publisher="Harpercollins" title="The Game" author="Neil Strauss"/>
	<book isbn="978-3832180577" publisher="Dumont Buchverlag" title="Feuchtgebiete" author="Charlotte Roche"/>
</bookstore>

Voici le code de sérialisation/désérialisation vers une String :

    public static  String getXml(final T object2convert) {
        final StringWriter writer = new StringWriter();
        try {
            final JAXBContext context = JAXBContext.newInstance(object2convert.getClass());
            final Marshaller m = context.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            m.marshal(object2convert, writer);
        } catch (final Exception e) {
            // Assert.fail(e.getMessage()); 		
            e.printStackTrace();
        }
        return writer.toString();
    }

    @SuppressWarnings("unchecked")
    public static  T fromXml(final String xml, final Class classe) {
        if (xml != null) {
            try {
                final InputStream is = new ByteArrayInputStream(xml.getBytes());
                final JAXBContext context = JAXBContext.newInstance(classe);
                final Unmarshaller um = context.createUnmarshaller();
                return (T) um.unmarshal(is);
            } catch (final Exception e) { 			
                // Assert.fail(e.getMessage()); 			
                e.printStackTrace(); 		
            } 	
        } 	
        return null; 
    }

5. Sources

http://www.vogella.com/articles/JAXB/article.html