getters
.
package
dans une classe Java, ce n'est pas légal, et cela génère une erreur de compilation. Comment doit-on s'y prendre ?
Pour annoter un package en Java, il faut créer un fichier nommé
package-info.java
, rangé à la racine de ce package. Ce fichier ressemble à un fichier de classe, sauf qu'il ne correspond pas à un nom de classe : le caractère "-" ne peut pas être utilisé pour construire un nom de classe.
Ce fichier ne peut contenir que le nom du package dans lequel il se trouve. Ce nom peut porter plusieurs informations :
Exemple 5. Un package annoté
// // fichier package-info.java // @XmlSchema ( xmlns = { @XmlNs(prefix="pau", namespaceURI="http://www.paumard.org/cours-jaxb"), @XmlNs(prefix="xsd", namespaceURI="http://www.w3.org/2001/XMLSchema") }, namespace="http://www.paumard.org/cours-jaxb", elementFormDefault=XmlNsForm.QUALIFIED, attributeFormDefault=XmlNsForm.UNQUALIFIED ) package org.paumard.cours.model ;
Exemple 6. Déclaration générée par
@XmlSchema
<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified" targetNamespace="http://www.paumard.org/cours-jaxb" xmlns:pau="http://www.paumard.org/cours-jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0" >
@XmlRootElement
associe la classe annotée avec un nœud racine d'un document XML. Dans les cas simples, c'est la seule annotation que l'on trouve sur une classe. Cette annotation est suffisante pour générer un document XML à partir d'une instance de cette classe.
@XmlType
permet plusieurs choses. Le point principal est son attribut
propOrder
, qui permet de fixer l'ordre dans lequel les champs de cette classe doivent être enregistrés dans le document XML.
Exemple 7. Utilisation de
@XmlType
// // classe Marin // @XmlRootElement(name="marin") @XmlType(propOrder={"nom", "prenom", "age"}) public class Marin { @XmlAttribute(name="id") private long id ; private String nom, prenom ; private age ; // reste de la classe }
@XmlAccessorType
indique comment JAXB doit prendre en compte les champs d'une classe. Tous les champs ou propriétés d'une classe sont pris en compte par défaut dans le processus de génération de documents XML, sauf ceux qui sont annotés
@XmlTransient
. Il est important de noter que, par défaut, JAXB prend en compte toutes les propriétés publiques, et les champs annotés. Si l'on annote un champ privé, sans annoter la classe avec
@XmlAccessType.FIELD
, les choses ont toutes les chances de mal se passer. Effectivement JAXB verra deux fois le même champ : une fois du fait de l'annotation, et la deuxième fois du fait qu'il prend en compte le
getter
public.
Les valeurs que peut prendre cette annotation sont les suivantes :
@XmlAccessType.FIELD
: indique que tous les champs non statiques de la classe sont pris en compte ;
@XmlAccessType.PROPERTY
: indique que toutes les paires de
getters
/
setters
sont prises en compte ;
@XmlAccessType.PUBLIC
: indique que toutes les paires de
getters
/
setters
et tous les champs publics non statiques seront pris en compte ;
@XmlAccessType.NONE
: indique qu'aucun champ ou propriété n'est pris en compte.
@XmlEnum
permet de préciser la façon dont les valeurs d'une énumération vont être écrites dans le code XML.
@XmlEnum
fonctionne comme l'annotation JPA
@EnumeratedType
, qui permet d'imposer d'écrire en base le nom des valeurs énumérées plutôt que le numéro d'ordre. Voyons un exemple de fonctionnement.
Exemple 8. Première utilisation de
@XmlEnum
et
@XmlEnumValue
// // énumération Grade // @XmlType @XmlEnum(String.class) public enum Grade { MATELOT, BOSCO, PACHA, CUISINIER } // // Schéma XML généré // <xsd:simpleType name="Grade"> <xsd:restriction base="xsd:string"/> <xsd:enumeration value="MATELOT"/> <xsd:enumeration value="BOSCO"/> <xsd:enumeration value="PACHA"/> <xsd:enumeration value="CUISINIER"/> </xsd:simpleType>
@XmlEnum
.
Exemple 9. Deuxième utilisation de
@XmlEnum
et
@XmlEnumValue
// // énumération Grade // @XmlType @XmlEnum(Integer.class) public enum Grade { @XmlEnumValue("10") MATELOT, @XmlEnumValue("20") BOSCO, @XmlEnumValue("30") PACHA, @XmlEnumValue("40") CUISINIER } // // Schéma XML généré // <xsd:simpleType name="Grade"> <xsd:restriction base="xsd:int"/> <xsd:enumeration value="10"/> <xsd:enumeration value="20"/> <xsd:enumeration value="30"/> <xsd:enumeration value="40"/> </xsd:simpleType>
int
. Il nous faut donc préciser les valeurs des entiers associées aux valeurs de notre énumération. C'est le rôle de l'annotation
@XmlEnumValue
, qui se place sur chaque valeur de l'énumération, et qui porte en attribut l'entier associé à cette valeur.
@XmlElement
permet d'associer un champ ou un
getter
à un nœud d'un document XML. Il permet de spécifier le nom de cet élément, son espace de nom, sa valeur par défaut, etc...
List
, alors on peut spécifier les choses plus finement. Une
List
Java permet d'enregistrer des éléments de différents types, soit non spécifiés (comme en Java 4), soit étendant une classe ou une interface donnée dans la déclaration de cette liste. Dans les deux cas, une liste peut porter des éléments de différentes classes.
En utilisant l'annotation
@XmlElements
, on peut spécifier que chaque élément de la liste, du fait de sa classe, est associée à un nœud différent.
Examinons l'exemple suivant, dans lequel les classes
Cuisinier
et
Capitaine
étendent
Marin
.
Exemple 10. Utilisation de @XmlElements
// // classe Bateau // @XmlRootElement(name="bateau") @XmlAccessorType(XmlAccessType.FIELD) public class Bateau { @XmlAttribute private long id ; @XmlElement(name="nom") private String nom ; @XmlElementWrapper(name="equipage") @XmlElements({ @XmlElement(name="marin", type=Marin.class), @XmlElement(name="capitaine", type=Capitaine.class), @XmlElement(name="cuisinier", type=Cuisinier.class) }) private List<Marin> equipage = new ArrayList<Marin>() ; // reste de la classe }
Exemple 11. Utilisation de
@XmlElements
: document XML généré
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <bateau xmlns:ns2="http://www.paumard.org/cours-jaxb" id="3"> <nom>Altaïr</nom> <equipage> <marin id="10"> <nom>Surcouf</nom> <age>0</age> </marin> <cuisinier id="20"> <nom>Cook</nom> <age>0</age> </cuisinier> <capitaine id="30"> <nom>Magellan</nom> <age>0</age> </capitaine> </equipage> </bateau>
Capitaine
dans un élément
capitaine
etc...
Notons la présence de l'annotation
@XmlWrapper
sur le champ
equipage
. C'est cette annotation qui permet de ranger les éléments
marin
,
capitaine
et
cuisinier
dans le sous-élément
equipage
. Si elle n'avait pas été présente, ces éléments auraient été rangés à plat dans l'élément
bateau
.
@XmlList
se pose sur des champs ou
getters
de type
List
, et n'est valide que lorsque ces listes portent des types primitifs Java, des classes enveloppe, ou des chaînes de caractères (
String
). Dans ce cas, la liste est écrite dans un unique élément XML, et ses éléments sont séparés par des espaces. Voyons ceci sur un exemple.
Exemple 12. Utilisation de
@XmlList
// // Classe Tableau // @XmlRootElement public class Tableau { @XmlElement @XmlList private List<String> nombres = new ArrayList<String>() ; public List<String> getNombres() { return this.nombres ; } // reste de la classe } // // code d'utilisation // public static void main(String... args) throws JAXBException { Tableau tableau = new Tableau() ; tableau.getNombres().add("un") ; tableau.getNombres().add("deux") ; tableau.getNombres().add("trois") ; JAXBContext context = JAXBContext.newInstance(Tableau.class) ; Marshaller marshaller = context.createMarshaller() ; marshaller.setProperty("jaxb.encoding", "UTF-8") ; marshaller.setProperty("jaxb.formatted.output", true) ; marshaller.marshal(tableau, new File("tableau.xml")) ; }
nombre
sont écrits dans le même éléments XML
nombres
.
Exemple 13. Utilisation de
@XmlList
: document XML généré
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tableau>
<nombres>un deux trois</nombres>
</tableau>
required
).
@XmlValue
. La présence de cette annotation indique que les instances de cette classe sont représentées par une valeur simple unique, donnée par le champ qui porte cette annotation. Ainsi, lorsque ces objets seront utilisés ailleurs, ils seront représentés par cette valeur simple.
Voyons un exemple d'utilisation.
Exemple 14. Utilisation de
@XmlValue
// // Classe Salaire // @XmlAccessorType(XmlAccessType.FIELD) public class Salaire { @XmlValue private int montant ; // reste de la classe } // // Classe Marin // @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Marin { private Salaire salaire ; // reste de la classe }
Exemple 15. Utilisation de
@XmlValue
: document XML généré
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<marin>
<salaire>100</salaire>
</marin>
salaire
ne comporte pas de sous-élément, il a été construit à partir de la valeur du champ annoté par
@XmlValue
.
@Path
@Produces
et
@Consumes
@Provider
MessageBodyReader
et
MessageBodyWriter