java et xml - jaxbprogrammation-java.1sur1.com/java/tutoriels/techniquessup/pdf/jax… · jaxb jaxb...

27
Java et XML - JAXB Chapitres traités Qu'est ce que le « Data Binding » ou association de données ? Le XML est aujourd'hui un format d'échange de donnéestrès utilisé. Il possède de nombreuxavantages: il est standard , simple , et surtoutfacile à lire. Il peut être lu par un homme, mais ce qui le plus intéressantc'est qu'il peut être lu par un ordinateur . En effet, la puissancedu XML repose sur le fait qu'il peut être analysé par un programmeet le contenu de ce flux est comprispar la machine . La structurede ce langagepermeten effet de comprendreles relationsentre toutes ces données . De ce fait, les programmeursont réaliséde nombreusesAPI permettantd'accéderaux donnéesXML à traversleurslangagesfavoris (DOM et SAX par exempleen Java). Néanmoins , ces dernièresont des inconvénients . Tous d'abord, il faut étudier et apprendreune nouvelle API. Puis, ils sont trop généraux . C'est-à-dire que le programmeurdoit adapterle code à son applicationà chaque fois qu'il veut accéderà des donnéesXML. Ensuite , il faut qu'il crée lui-même toutes les classespermettantde gérer ces nouvellesdonnéesdans son programme , cela lui prend doncbeaucoupde temps. Pour remédier à ces inconvénients, il existe le « Data Binding » également appelé en français : association de données. En java, Sun a réalisé une API nommée JAXB (Java Architecture for XML Binding) pour simplifier les processus de transformation d’objets Java en fichier XML, et de fichier XML en objets Java. JAXB est une spécification qui permet de faire correspondre un document XML à un ensemble de classes et vice et versa via des opérations de sérialisation/ désérialisation nommée marshaling/unmarshaling. JAXB permet aux développeurs de manipuler un document XML sans à avoir connaître XML ou la façon dont un document XML est traitée comme cela est le cas avec SAX, DOM ou STAX. La manipulation du document XML se fait en utilisant des objets précédemment générés à partir d'une DTD pour JAXB 1.0 et d'un schéma XML du document à traiter pour JAXB 2.0. Qu'est ce que le « Data Binding » ou associationde données ? Le Data Binding est une technologie permettant d'automatiser la transformation d'un modèle de données en un modèle de données objets dans un langage de programmation. Autrement dit, il permet par exemple de convertir les fichiers XML en instances de classes Java. Pour réaliser cela, il y a trois étapes : 1. La génération de classes. 2. Le rassemblementdes données. 3. La redistribution des données Le schéma suivant résume assez bien le principe : un document XML suit les règles de grammaire du « schema », ce dernier une fois compilé permet de créer une classe correspondante. Cette dernière permettra de créer une instance d'objet correspondant :

Upload: nguyenkhuong

Post on 13-Sep-2018

270 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Java et XML - JAXB

Chapitres traités Qu 'est ce que le « Data Binding » ou association de données ?

Le XML est aujourd'hui un format d'échange de données très ut ilisé. Il possède de nombreuxavantages : il est standard, si mple, etsurtout facile à lire. Il peut être lu par un homme, mais ce qui le plus intéressantc'est qu'il peut être lu par un ordinateu r. En effet, lapuissancedu XML repose sur le fait qu'il peut être analysé pa r un programmeet le contenu de ce flux est comprispar la machi ne. Lastructurede ce langagepermeten effet de comprendreles rel ationsentre toutes ces données.

De ce fait, les programmeursont réaliséde nombreusesAPI pe rmettantd'accéderaux donnéesXML à traversleurs langages favoris (DOMet SAX par exemple en Java). Néanmoins, ces dernièresont des inconvénients. Tous d'abord, il faut étudier et apprendreu ne nouvelle

API. Puis, ils sont trop généraux. C'est-à-dire que le progr ammeurdoit adapterle code à son applicationà chaque fois qu 'il veut accéderà des donnéesXML. Ensuite,il faut qu'il crée lui-même toutes les classespermettantde gérer ces nouvellesdonnéesdans son programme, cela lui pre nd doncbeaucoupde temps.

Pour remédier à ces inconvénients, il existe le « Data Binding » également appelé en français : association de données . En java, Sun a réalisé une APInommée JAXB (Java Architecture for XML Binding) pour simplifier les pro cessus de transformation d’objets Java en fichier XML, et de fichier XML en objetsJava.

JAXB est une spécification qui permet de faire correspondre un do cument XML à un ensemble de classes et vice et versa via des opé rations de sérialisation/désérialisation nommée marshaling/unmarshaling .

JAXB permet aux développeurs de manipuler un document XML sa ns à avoir connaître XML ou la façon dont un document XML est tr aitée comme cela est lecas avec SAX, DOM ou STAX.

La manipulation du document XML se fait en utilisant des obje ts précédemment générés à partir d'une DTD pour JAXB 1.0 et d' un schéma XML du documentà traiter pour JAXB 2.0.

Qu'est ce que le « Data Binding » ou associationde données ?

Le Data Binding est une technologie permettant d'automatis er la transformation d'un modèle de données en un modèle de do nnées objets dans un langage deprogrammation. Autrement dit, il permet par exemple de conv ertir les fichiers XML en instances de classes Java.

Pour réaliser cela, il y a trois étapes :

1. La génération de classes.

2. Le rassemblementdes données.

3. La redistribution des données

Le schéma suivant résume assez bien le principe : un document XML suit les règles de grammaire du « schema », ce dernier une f ois compilé permet decréer une classe correspondante. Cette dernière permettra de créer une instance d'objet correspondant :

Page 2: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

JAXB

JAXB est l'acronyme de Java Architecture for XML Binding. Le but d e l'API et des spécifications JAXB est de faciliter la manipulation d'un document XML engénérant un ensemble de classes qui fournissent un niveau d' abstraction plus élevé que l'utilisation de JAXP (SAX ou DOM).

Avec ces deux API, SAX et DOM, toute la logique de traitements des données contenues dans le document est à écrire.§

JAXB au contraire fournit un outil qui analyse un schéma XML et gén ère à partir de ce dernier un ensemble de classes qui vont enca psuler les traitements demanipulation du document. Le grand avantage est de fournir a u développeur un moyen de manipuler un document XML sans conn aître XML ou lestechnologies d'analyse. Toutes les manipulations se font a u travers d'objets java. Ces classes sont utilisées pour fai re correspondre le document XML dansdes instances de ces classes et vice et versa : ces opérations se nomment respectivement unmarshalling et marshalling .

JAXB 2.0

JAXB 2.0 a été développé sous la JSR 222 et elle est incorporée dans Java EE 5 et dans Java SE 6. Les fonctionnalités de JAXB 2. 0 par rapport à JAXB 1.0sont :

1. Support uniquement des schémas XML (les DTD ne sont plus su pportées).

2. Mise en oeuvre des annotations.

3. Assure la correspondance bidirectionelle entre un schém a XML et le bean correspondant.

4. Utilisation de fonctionnalités proposées par Java 5 nota mment les generiques et les énumérations.

5. Le nombre d'entités générées est moins important : JAXB 2. 0 génère une classe pour chaque complexType du schema alors que JAXB 1.0 génère uneinterface et une classe qui implémente cette interface. Une méthode de la classe ObjectFactory est générée pour renvoyée une instance de cette classe.

En plus de son utilité principale, JAXB 2.0 propose d'atteindreplusieursobjectifs :

1. Être facile à utiliser pour consulter et modifier un docum ent XML sans connaissance ni de XML ni de techniques de traite ment de documents XML.

2. Être configurable : JAXB met en oeuvre des fonctionnalité s par défaut qu'il est possible de modifier par configuratio n pour répondre à ces propresbesoins.

3. S'assurer que la création d'un document XML à partir d'obj ets et retransformer ce document en objets donne le même ense mble d'objets.

4. Pouvoir valider un document XML ou les objets qui encapsul ent un document sans avoir à écrire le document correspondan t.

5. Être portable : chaque implémentation doit au minimum met tre en oeuvre les spécifications de JAXB.

L'utilisationde JAXB implique généralementdeux étapes :

1. Génération des classes et interfaces à partir du schéma XM L.

2. Utilisation des classes générées et de l'API JAXB pour tra nsformer un document XML en graphe d'objets et vice et versa, pour manipuler les donnéesdans le graphe d'objets et pour valider le document.

Page 3: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Sérialisation

La sérialisation d'un graphe d'objets Java est effectué par une opération dite de mashalling . L'opération inverse est dite d' unmashalling . Lors de ces deuxopérations, le document XML peut être validé.

L'APIJAXB

L'API JAXB propose un framework composé de classes regroupé es dans trois packages :

1. javax.xml.bind : Contient les interfaces principales et la classe JAXBContext .

2. javax.xml.bind.util : Contient des utilitaires.

3. javax.xml.bind.helper : Contient une implémentation partielle de certaines inter faces pour faciliter le développement d'une implémentatio n des spécificationsde JAXB.

4. javax.xml.bin.annotation : Gestion des annotations pour préciser le mapping entre les classes Java et le document XML correspondant.

Annotations

JAXB 2.0 utilise de nombreuses annotations définies dans le package javax.xml.bin.annotation essentiellement pour préciser le mode de fonctionnement lo rs desopérations de marshaling/unmarshaling .

Ces annotations précisent le mapping entre les classes Java et le document XML. La plupart de ces annotations ont des vale urs par défaut ce qui réduitl'obligation de leur utilisation si la valeur par défaut cor respond au besoin.

Transformations

JAXB 2.0 permet aussi de réaliser dynamiquement à l'exécution une tr ansformation d'un graphe d'objets en document XML et vice et versa. C'est cettefonctionnalité qui est largement utilisée dans les service s web via l'API JAX−WS 2.0. La classe abstraite JAXBContext fournie par l'API JAXB permet de gérer latransformation d'objets Java en XML et vice et versa.

Outilsde JAXB2.0

JAXB 2.0 propose plusieurs outils pour faciliter sa mise en oeuvre :

1. Un générateur de classes Java (schema compiler) à partir d 'un schéma XML nommé xjc dans l'implémentation de référence. Ces classes générées m ettenten oeuvre les annotations de JAXB.

Page 4: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

2. Un générateur de schéma XML (schema generator) à partir d' un graphe d'objets nommé schemagen dans l'implémentation de référence.

L'API JAXB est contenue dans la package javax.xml.bind .§

La mise en oeuvrede JAXB2.0

La mise en oeuvre de JAXB requiert pour un usage standard plusieurs étapes :

1. La génération des classes en utilisant l'outil xjc de JAXB à partir d'un schéma du document XML.

2. Ecriture de code utilisant les classes générées et l'API J AXB pour :Transformer un document XML en objets Java.

Modifier des données encapsulées dans le graphe d'objets.

Transformer le graphe d'objets en un document XML avec une va lidation optionnelle du document.

3. Compilation du code généré.

4. Exécution de l'application.

Utilisationde JAXB2.0

L'utilisation de JAXB se fait donc en deux phases :

1. Générer des classes à partir d'un schéma XML et utiliser ce s classes dans le code de l'application.

2. Â l'exécution de l'application, le document XML est trans formé en graphe d'objets, les données de ces objets peuvent ê tre modifiées puis le document XMLpeut être regénéré à partir des objets.

Page 5: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

L'utilisationde JAXB met en oeuvre plusieurséléments :

1. Une ou plusieurs classes annotées qui vont encaspulées de s données du document XML.

2. Un schéma XML (optionnel) : c'est un document XML qui décri t la structure des éléments, attributs et entités d'un docum ent XML. Le but d'un schémaXML est similaire à celui d'une DTD mais le schéma propose une description plus riche et plus fine. Ce schéma peut éventuel lement être enrichi de donnéesde configurations concernant les classes à générer.

3. Un outil (optionnel) qui génère les classes annotées à par tir d'un schéma avec éventuellement un fichier de configura tion pour configurer les classes àgénérer.

4. Une API utilisée à l'exécution pour transformer un docume nt XML en un ensemble d'objets du type des classes annotées et vice et versa et permettre desvalidations.

5. Un document XML qui sera lu et/ou écrit en fonction des trai tements à réaliser.

Avantages

Les avantages d'utiliser JAXB sont nombreux :

1. Facilite la manipulation de document XML dans une applica tion Java.

2. Manipulation du document XML au travers d'objets : aucune connaissance de XML ou de la manière de traiter un document n' est requise.

3. Un document XML peut être créé en utilisant les classes gén érées.

4. Les traitements de JAXB peuvent être configurés.

5. Les ressources requises par le graphe d'objets utilisé pa r JAXB sont moins importantes qu'avec DOM.

Inconvénients

Si vous devez créer des classes directement à partir d'un doc ument XML, vous devez impérativement posséder le Schéma XML correspondant (avec l'extension xsd). Si vous n'avez pas le Schéma XML, cela peut poser quelques di fficultés. C'est l'inconvénient de cette technologie.

Toutefois, il existe des logiciels libres, comme Liquid XML Studio , qui savent créer un Schéma directement à partir du document XML correspondant. Ilsproposent alors des valeurs par défaut que vous pouvez par la suite modifier au travers des propriétés proposées dans l'é diteur intégré.

Générer des classes à partir d'un schéma

Pour permettre l'utilisation et la manipulation d'un docum ent XML, JAXB propose de générer un ensemble de classes à part ir du schema XML du document.

Chaque implémentation de JAXB doit fournir un outil (bindin g compiler) qui permet la génération de classes et interface s à partir d'un schema (binding aschema).

Page 6: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Exemplede documentXMLavecson SchémaXMLassocié

Je vous propose, pour la suite de cette étude, de prendre un ex emple concret, et surtout très simple. J'aimerais pouvoir m ettre en oeuvre un logiciel qui trace desformes, des carrés ou des cercles, dans la partie principale d'une application graphique fenêtrée.

Il doit être possible de récupérer l'ensemble des formes à tr acer au moyen, par exemple, du document XML ci-dessous :

En utilisant le logiciel Liquid XML Studio , et en faisant les réglages nécessaires, voici le Schéma XML correspondant :

La commandexjc

Page 7: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Comme nous l'avons vu, l'implémentation de référence fourn it l'outil xjc pour générer les classes à partir d'un schéma XML. L'utilisa tion la plus simple de l'outil xjcest de lui fournir simplement le fichier qui contient le sché ma XML du document à utiliser.

xjc Formes.xsd

L'outil xjc possède plusieursoptions dont voici les principales:

Option Rôle

-p nom_package Précise le package qui va contenir les classes générées

-d répertoire Précise le répertoire qui va contenir les classes générées

-nv Inhibe la validation du schéma

-b fichier Précise un fichier de configuration

-classpath chemin Précise le classpath

Les classesgénérées

Le compilateur génère des classes en correspondance avec le Schéma XML fourni à l'outil.

Deux entités sont généréesdans le répertoire generated :

1. Formes. java : classes qui encaspulent le document XML. Chaque classse qu i encapsule un type complexe du schéma possède des getter et s etter sur leséléments du schéma.

2. ObjectFactory. java : fabrique qui permet d'instancier des objets utilisés lors du mapping. La fabrique permet de créer des instances de chac un des typesd'objet correspondant à un type complexe du schéma. Cette fa brique est particulièrement utile lors de la création d'un n ouveau document XML : le graphed'objets est créé en ajoutant des instances des objets retou rnées par cette fabrique.

Les classes générées sont dépendantes de l'implémentation de JAXB utilisée : il est préférable d'utiliser les classes g énérées par une implémentation aveccet outil. Par défaut, JAXB utilise des règles pour définir c haque entité incluse dans le schema ( element et complexType défini dans le schéma).

Formes.java (sans les commentaires)

package jaxb ; / / ---------------------------------------------------------------------------------------------------------- Ligne rajoutée

import java.util .ArrayList ;import java.util .List ;import javax .xml .bind .annotation .*;

@XmlAccessorType (XmlAccessType.FIELD ) / / ------------------------------------------------------------ Element racine@XmlType(name = "" , propOrder = {"forme" })@XmlRootElement (name = "Formes" )public class Formes {

@XmlElement (name = "Forme" ) protected List <Formes.Forme > forme ;

Page 8: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

public List <Formes.Forme > getForme () { if (forme == null) { forme = new ArrayList <Formes.Forme >(); } return this . forme ; }

@XmlAccessorType (XmlAccessType.FIELD ) / / ----------------------------------------------------- Element Forme @XmlType(name = "" , propOrder = {"centre" , "largeur" }) public static class Forme {

protected Formes.Forme.Centre centre ;

@XmlSchemaType (name = "unsignedInt" ) protected Long largeur ;

@XmlAttribute (required = true) protected String type ;

public Formes .Forme.Centre getCentre () { return centre ; } public void setCentre (Formes .Forme.Centre value ) { this .centre = value ; }

public Long getLargeur () { return largeur ; } public void setLargeur (Long value ) { this . largeur = value ; }

public String getType () { return type ; } public void setType (String value ) { this . type = value ; }

@XmlAccessorType (XmlAccessType.FIELD ) / / --------------------------------------------------- Element Centre @XmlType(name = "" ) public static class Centre {

@XmlAttribute (required = true) protected int x ;

@XmlAttribute (required = true) protected int y ;

public int getX() { return x ; } public void setX (int value ) { this .x = value ; }

public int getY() { return y ; } public void setY (int value ) { this .y = value ; } } }}

ObjectFactory.java (sans les commentaires)

package jaxb ; / / ---------------------------------------------------------------------------------------------------------- Ligne rajoutée

import javax .xml .bind .annotation .XmlRegistry ;

@XmlRegistrypublic class ObjectFactory {

public ObjectFactory() {}

public Formes .Forme createFormesForme() { return new Formes .Forme(); }

public Formes createFormes() { return new Formes(); }

public Formes .Forme.Centre createFormesFormeCentre() { return new Formes .Forme.Centre(); }}

Utiliser l'API JAXB 2.0

JAXB fournie une API qui permet à l'exécution d'effectuer le s opérations de transformation d'un document XML en un graph e d'objets utilisant les classes généréeset vice et versa ( unmashalling/marshalling ) ainsi que des opérations de validation.

1. L'objet principal pour les opérations de transformation est l'objet JAXBContext : il permet d'utiliser l'API JAXB. Pour obtenir une instance de cet objet, ilsuffit d'utiliser la méthode statique newInstance() en lui passant en argument le ou les paquetages contenant les classes générées à utiliser. Dans le cas ouplusieurs paquetages doivent être précisés, il faut les sép arer par une virgule.

JAXBContext contexte = JAXBContext .newInstance ("jaxb");

2. Une autre surdéfinition de la méthode newInstance() attend en argument la classe qui encapsule la racine du docum ent.

Mapperun documentXMLà desobjets(unmarshal)

L'API JAXB propose de transformer un document XML en un ensem ble d'objets qui vont encapsuler les données et la hiérarchi e du document. Ces objets sont desinstances des classes générées à partir du schéma XML.

Page 9: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

1. La création des objets nécessite la création d'un objet de type JAXBContext en utilisant la méthode statique newInstance() , comme nous venons de ledécouvrir.

2. Il faut ensuite instancier un objet de type Unmarshaller qui va permettre de transformer un document XML en un ensembl e d'objets. Un telle instance estobtenue en utilisant la méthode createUnmarshaller() de la classe JAXBContext .

Unmarshaller mapperXMLObjet = contexte .createUnmarshaller();

3. La méthode unmarshal() de la classe Unmarshaller se charge de traiter un document XML et retourne un objet du ty pe complexe qui encapsule la racine dudocument XML. Elle possède de nombreuses surdéfinitions à u tiliser en fonction des besoins.

Formes formes = (Formes) mapperXMLObjet .unmarshal( new File( "Formes.xml" ));

4. A partir de cet objet, il est possible d'obtenir et de modif ier des données encapsulées dans les différents objets créé s à partir des classes générées et ducontenu du document. Chacun de ces objets possèdent des getter et des setter sur leur noeud direct.

Exemplede mise en oeuvreau traversde l'applicationfenêtrée

Je vous propose de finaliser ces concepts au travers de l'app lication fenêtrée qui trace les formes stockées dans le docu ment XML, dont voici le résultat :

Codage de l'applicationfenêtrée

package jaxb ;

import java.awt .*;import java. io .File ;import javax .swing .*;import javax .xml .bind .*;

public class Principal extends JFrame { private Tracé dessins = new Tracé() ;

public Principal() { super ("Tracé de formes" ); add(dessins ); setSize (400, 300); setLocationRelativeTo (null ); setDefaultCloseOperation (EXIT_ON_CLOSE); setVisible (true ); }

public static void main(String [] args ) { new Principal(); }

private class Tracé extends JComponent { private Formes formes; public Tracé() { try { JAXBContext contexte = JAXBContext .newInstance ("jaxb" ); Unmarshaller mapperXMLObjet = contexte .createUnmarshaller (); formes = (Formes) mapperXMLObjet .unmarshal (new File ("Formes.xml" )); } catch (JAXBException ex) { setTitle ("Impossible de récupérer le document XML" ); } }

@Override protected void paintComponent (Graphics g) { super .paintComponent (g); Graphics2D surface = (Graphics2D ) g; surface .setStroke (new BasicStroke (5)); surface .setRenderingHint (RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON ); if (formes !=null ) for (Formes.Forme forme : formes .getForme() ) { long largeurLong = forme .getLargeur() ;

Page 10: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

int largeur = (int ) largeurLong ; int x = forme .getCentre() .getX() - largeur /2; int y = forme .getCentre() .getY() - largeur /2; String type = forme .getType() ; if (type .equals ("Carré" )) surface .drawRect (x , y , largeur , largeur ); else surface .drawOval (x , y , largeur , largeur ); } } }}

Créerun documentXMLà partird'objets

JAXB permet de créer un document XML à partir d'un graphe d'ob jets : cette opération est nommée marshalling . Une operation de mashalling est l'opération inversede l'opération d' unmarshalling .

Ce graphe d'objets peut être issu d'une opération de type unmarshalling (construction à partir d'un document XML existant) ou issu d 'une création de toutespièces de l'ensemble des objets. Dans le premier cas cela cor respond à une modification du document et dans le second cas à une création de document.

1. La création des objets nécessite la création d'un objet de type JAXBContext en utilisant la méthode statique newInstance() , comme précédemment.

2. Il faut ensuite instancier un objet de type Marshaller qui va permettre de transformer un ensemble d'objets en un do cument XML. Un telle instance estobtenue en utilisant la méthode createMarshaller() de la classe JAXBContext .

3. La méthode marshal() de la classe Marshaller se charge de créer un document XML à partir d'un graphe d'obje ts dont l'objet racine lui est fourni enparamètre. La méthode marshal() possède plusieurs surdéfinition qui permettent de précise r la forme du document XML généré :

un fichier ( File),

un flux ( OutputStream ),

un flux de caractère ( Writer ),

un document DOM ( Document ),

un gestionnaire d'événement SAX ( ContentHandler ),

un objet de type javax.xml. transform.SAXResult ,

un objet de type javax.xml. transform.DOMResult ,

un objet de type javax.xml. transform.StreamResult ,

un objet de type javax.xml.stream.XMLStreamWriter ,

ou un objet de type javax.xml.stream.XMLEventWriter .

4. L'objet Mashaller possède des propriétés qu'il est possible de valoriser en ut ilisant la méthode setProperty() . Les spécifications de JAXB proposent despropriétés qui doivent être obligatoirement supportées pa r l'implémentation. Chaque implémentation est libre de pro poser des propriétés supplémentaires.

JAXB_ENCODING : Permet de préciser le jeux de caractères d'encodage du docu ment XML.

JAXB_FORMATTED_OUTPUT : Booléen qui indique si le document XML doit être formaté.

Exemple : demander le formattage du document créé :

Marshaller mapperObjetsXML = contexte .createMarshaller();mapperObjetsXML .setProperty( Marshaller .JAXB_FORMATTED_OUTPUT , true );

La création d'un document XML à partir d'objets peut se faire suivant deux approches qui seront traitées dans les chapitr es qui suivent :

1. En utilisant les classes générées à partir d'un Schéma XML .

2. En utilisant des classes annotées sans être obligé d'utiliser un Schéma XML .

Création d'un document XML à partir d'objets suivant un Schéma XML

Comme nous l'avons découvert dans les chapitres précédents , une des classes générées à partir du schéma se nomme ObjectFactory : c'est une fabrique d'objetspour les classes générées qui encapsulent des données d'un d ocument respectant le schéma.

Pour créer un document XML en utilisant ces classes, il faut suivre les étapes que nous avons évoquédans la fin du chapitre précédent :

1. La création du document nécessite la création d'un objet d e type JAXBContext en utilisant la méthode statique newInstance() .

2. Il faut ensuite créer le graphe d'objets en utilisant la cl asse ObjectFactory pour instancier les différents objets et valoriser les donn ées de ces objets enutilisant les setter .

ObjectFactory fabrique = new ObjectFactory() ; Formes formes = fabrique. createFormes() ;Formes.Forme forme = fabrique. createFormesForme() ;Formes.Forme.Centre centre = fabrique. createFormesFormeCentre() ;

Page 11: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

3. Il faut ensuite créer un objet de type Marshaller à partir du contexte et appeler sa méthode marshall() pour générer le document.

Exemplede mise en oeuvreau traversde l'applicationfenêtrée

Je vous propose de finaliser ces concepts au travers d'une ap plication fenêtrée qui trace les formes directement sur la z one principale de la fenêtre et qui peutstocker par la suite tous les formes présentes dans le docume nt XML correspondant :

Codage de l'applicationfenêtrée

package jaxb ;

import java.awt .*;import java.awt .event.*;import java. io .File ;import javax .swing .*;import javax .xml .bind .*;

public class Principal extends JFrame { private Tracé dessins = new Tracé() ; private JRadioButton cercle = new JRadioButton ("Cercle" , true ); private JRadioButton carré = new JRadioButton ("Carré" ); private JFormattedTextField largeur = new JFormattedTextField (50L); private ButtonGroup groupe = new ButtonGroup (); private JPanel boutons = new JPanel (); private JToolBar barre = new JToolBar ();

public Principal() { super ("Tracé de formes" ); add(barre , BorderLayout.NORTH ); barre .add(new AbstractAction ("Nouveau" , new ImageIcon ("nouveau.gif" )) { public void actionPerformed (ActionEvent e) { dessins .effacer(); } }); barre .add(new AbstractAction ("Enregistrer" , new ImageIcon ("enregistrer.gif" )) { public void actionPerformed (ActionEvent e) { dessins .enregistrer(); } }); dessins .addMouseListener (new MouseAdapter () { @Override public void mouseClicked (MouseEvent e) { if (cercle . isSelected ()) dessins .ajoutForme ("Cercle" , e.getX(), e.getY()); else dessins .ajoutForme ("Carré" , e.getX(), e.getY()); } }); add(dessins ); largeur .setColumns (5); boutons .add(cercle ); boutons .add(carré ); boutons .add(largeur ); groupe .add(cercle ); groupe .add(carré ); add(boutons , BorderLayout.SOUTH ); setSize (400, 300); setLocationRelativeTo (null ); setDefaultCloseOperation (EXIT_ON_CLOSE); setVisible (true ); }

public static void main(String [] args ) { new Principal(); }

private class Tracé extends JComponent { private Formes formes ; private Marshaller mapperObjetsXML ; private ObjectFactory fabrique = new ObjectFactory() ; public Tracé() { try { JAXBContext contexte = JAXBContext .newInstance (Formes .class ); mapperObjetsXML = contexte .createMarshaller() ; mapperObjetsXML .setProperty (Marshaller .JAXB_FORMATTED_OUTPUT, true); formes = fabrique .createFormes() ; }

Page 12: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

catch (JAXBException ex) { setTitle ("Impossible de créer le document XML" ); } }

@Override protected void paintComponent (Graphics g) { super .paintComponent (g); Graphics2D surface = (Graphics2D ) g; surface .setStroke (new BasicStroke (5)); surface .setRenderingHint (RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON ); if (formes !=null) for (Formes.Forme forme : formes .getForme() ) { long largeurLong = forme .getLargeur(); int largeur = (int ) largeurLong ; int x = forme .getCentre().getX() - largeur /2; int y = forme .getCentre().getY() - largeur /2; String type = forme .getType() ; if (type .equals ("Carré" )) surface .drawRect (x , y , largeur , largeur ); else surface .drawOval (x , y , largeur , largeur ); } }

public void effacer() { formes = fabrique .createFormes(); revalidate (); repaint (); }

public void ajoutForme (String type , int x , int y ) { Formes.Forme forme = fabrique .createFormesForme(); forme .setType (type ); forme .setLargeur ((Long ) largeur .getValue()); Formes.Forme.Centre centre = fabrique .createFormesFormeCentre(); centre .setX (x); centre .setY (y); forme .setCentre (centre ); formes .getForme().add( forme ); repaint (); }

private void enregistrer() { try { mapperObjetsXML .marshal (formes , new File ("Formes.xml" )); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } } }}

Mapping XML/Objets en passant par les annotations

JAXB permet de mapper un document XML vers une ou plusieurs cl asses annotées, ou inversement, sans être obligé d'utiliser un schéma XML . Dans ce cas, ledéveloppeur a la charge d'écrire la ou les classes annotées r equises.

Dans nos développement, il arrive très souvent que nous mani pulions un ensemble d'informations, de différentes nature s, comme un système de gestion depersonnel ou encore comme le logiciel de tracé de formes. Ces informations sont toujours structurées sous forme de class es, et derrière, nous manipulonsles objets correspondants.

Nous avons quelquefois besoin de pouvoir stocker ces inform ations dans un fichier afin de les retrouver par la suite. Se p ose alors la question duformat de stockage. Nous avons vu que le document XML est une b onne alternative puisqu'il est facile de le lire avec un simp le éditeur de texte.

Dans ce contexte, il serait judicieux de pouvoir fabriquer c es documents XML directement par l'intermédiaire des class es déjà existantes (mappingObjets/XML), sans passer par un Schéma XML (puisqu'encore a ucun document n'existe). C'est dans ce cadre là que nous pouv ons rajouter desannotations spécifiques directement sur les classes conce rnées.

Il n'est donc plus nécessaire d'utiliser des classes généré es par le compilateur de schéma mais dans ce cas, la ou les clas ses doivent être crééesmanuellement en utilisant les annotations adéquates. La cl asse qui encapsule la racine du document doit être annotée av ec l'annotation @XmlRootElement .Une exception de type javax.xml.bind.MarshalException est levée par JAXB si la classe racine ne possède pas cette ann otation.

JAXB utilise des comportements par défaut qui ne nécessite d e la part du développeur que de définir des comportements par ticuliers si la valeur par défautne convient pas. Ainsi, nous pouvons limiter le nombre d'ann otations requises.

Communicationentre le documentXMLet les objetscorrespondants

Comme nous l'avons découvert dans les chapitres précédents , le mapping entre un document XML et les objets correspondan ts, se feront par l'intermédiaires desclasses JAXBContext , Marshaller et Unmarshaller .

1. La création ou la connexion avec un document XML nécessite la création d'un objet de type JAXBContext en utilisant la méthode statique newInstance() .

2. Il faut ensuite créer un objet de type Marshaller à partir du contexte et d'appeler sa méthode marshall() pour générer le document XML à partir des objetsdéjà créés.

3. Ou bien créer un objet de type Unmarshaller à partir du contexte et d'appeler sa méthode unmarshall() pour générer les objets correspondant au documentXML.

Page 13: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Annotationdes classes

La configuration de la transformation d'un document XML en o bjets Java est réalisée grâce à l'utilisation d'annotation s dédiées dans les classes Java. Denombreuses annotations sont définies par JAXB 2.0. Toutes c es annotations sont définies dans le package javax.xml.bind.annotation .

Annotation Description

XmlAccessorOrder Contrôler l 'ordre des attributs et des propriétés dans la cl asse.

XmlAccessorType Contrôler si l 'attribut ou la propriété de la classe est séri alisé par défaut.

XmlAnyAttribute Convertir une propriété de la classe en un ensemble d'attrib uts de type jocker dans le document XML.

XmlAnyElement Convertir une propriété de la classe en une description repr esentant l 'élément JAXB dans le document XML.

XmlAttachmentRef Marquer un attribut ou une propriété de la classe comme une UR I que fait référence à une type MIME particulier.

XmlAttribute Convertir une propriété de la classe en un attribut dans le do cument XML.

XmlElement Convertir une propriété de la classe en un élément dans le doc ument XML.

XmlElementDecl Associer une fabrique à un element XML.

XmlElementRef Convertir une propriété de la classe en un élément dans le doc ument XML qui est associé à un nom de propriété particulier.

XmlElementRefs Marquer une propriété de la classe qui fait référence aux cla sses qui possèdente XmlElement ou JAXBElement .

XmlElements Créer un conteneur pour de multiples annotations XmlElement , qui précise ainsi le choix possible parmi celles qui sont pr oposées.

XmlElementWrapper Créer un élément père dans le document XML pour des collectio ns d'éléments.

XmlEnum Convertir une énumération en une représentation équivalen te dans le document XML.

XmlEnumValue Convertir un énumérateur en une représentation équivalent e dans le document XML.

XmlID Convertir une propriété de la classe en un ID XML.

XmlIDREF Convertir une propriété de la classe en un IDREF XML.

XmlInlineBinaryData Encoder en base64 dans le document XML.

XmlList Utilisé pour convertir une propriété de la classe vers une li ste de type simple.

XmlMimeType Associer un type MIME qui contrôle la représentation XML en r apport avec la propriété de la classe.

XmlMixed Annoter une propriété de la classe qui peut supporter plusie urs types de valeur avec un contenu mixte.

XmlNs Associer un prefix d'un espace de nommage à une URI.

XmlRegistry Marquer une classe comme possédant une ou des méthodes annot ées avec XmlElementDecl .

XmlRootElement Associer une classe ou une énumération à un element XML. Très souvent utilisé pour spécifier la racine du document XML.

XmlSchema Associer un espace de nommage à un paquetage.

XmlSchemaType Associer un type Java ou une énumeration à un type défini dans un schéma.

XmlSchemaTypes Conteneur pour plusieurs propriétés annotées par XmlSchemaType .

XmlTransient Marquer une entité pour qu'elle ne soit pas mappée dans le doc ument XML.

XmlType Convertir une classe ou une énumération vers le type spécifi é dans Shéma XML correspondant.

XmlValue Mapper une classe vers le type complexe dans le Schéma XML ou v ers le type simple suivant le cas.

Premierexemplede mise en oeuvre- pasd'attributsdans les balises

Nous allons toute de suite élaborer un premier exemple qui pe rmet de faire du tracé de formes, comme précédemment, avec la possiblité de sauvegarder le tracéréalisé sur l'IHM dans un document XML et de pouvoir ensuite l e restituer à loisir. Tout ceci se fait sans document XML préa lable, et à plus forte raison, sansSchéma XML équivalent.

Dans ce premier exemple, nous ne proprosons pas d'attributs dans les balises. Du coup, il devient nécessaire de prévoir d es balises spécifiques pour lescoordonnées. Remarquez au passage que notre document Formes , représenté par l'élément racine <formes> peut aussi bien accueillir des éléments <cercle>que des éléments <carré> , ce qui offre une structure un petit peu plus compliquée que p récédemment.

Page 14: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Mise en place du sourcerelatif aux formes

package jaxb ;

import java.awt .Graphics2D ;import java.util .ArrayList ;import javax .xml .bind .annotation .*;

/ / Définition de l 'élément racine du document et de ses sous-éléments@XmlRootElementpublic class Formes { @XmlElements ({ @XmlElement (name = "carré" , type = Carré.class ), @XmlElement(name = "cercle" , type = Cercle.class ) }) private ArrayList <Forme> formes = new ArrayList <Forme>();

public ArrayList <Forme> getFormes() { return formes ; } public void ajoutForme( Forme forme ) { formes .add(forme ); } public void supprimerFormes() { formes .clear (); }}

/ / hiérarchie des classes représentant l 'ensemble d es formes possiblesabstract class Forme { protected int x , y ; public Forme() {} public Forme(int x , int y ) { this .x = x ; this .y=y; } public int getX() { return x ; } public void setX (int x ) { this .x = x ; } public int getY() { return y ; } public void setY (int y ) { this .y = y ; } abstract void dessine (Graphics2D surface );}

class Cercle extends Forme { private int rayon = 50; public Cercle() {} public Cercle(int x , int y , int rayon ) { super (x , y ); this .rayon = rayon ; } public int getRayon () { return rayon ; } public void setRayon (int rayon ) { this . rayon = rayon ; } @Override void dessine (Graphics2D surface ) { surface .drawOval (x -rayon , y -rayon , 2*rayon , 2*rayon ); }}

class Carré extends Forme { private int côté = 100; public Carré() {} public Carré(int x , int y , int côté ) { super (x , y ); this .côté = côté ; } public int getCôté () { return côté ; } public void setCôté (int côté ) { this .côté = côté ; } @Override void dessine (Graphics2D surface ) { surface .drawRect (x -côté /2, y -côté /2, côté , côté ); }}

Dans ce source, nous découvronsdeux parties essentielles:

1. La hiérarchie des classes qui représente l'ensemble des f ormes, avec même une classe de base abstraite. Ce sont ces cla sses que nous utilisonsdirectement dans l'IHM. Remarquez, qu'elles ne possèdent a ucune annotation particulière.

2. La première partie du code est cette fois-ci plus spécifiq ue à l'élaboration du document XML. Dans ce cadre là, une clas se Formes est spécialement crééepour représenter l'élément racine du document qui est spéci fié au travers de l'annotation @XmlRootElement .

3. Cette classe Formes possède un seul attribut : formes qui représente l'ensemble des formes susseptibles d'être e nregistrées. Comme il existe plusieursformes possibles, nous utilisons une annotation particuli ère, juste au-dessus de l'attribut, qui va servir à préciser quels sont les éléments autorisés àintégrer l'ensemble des formes. Il s'agit de l'annotation @XmlElements à l'intérieur de laquelle nous allons positionner des annot ations de type @XmlElement qui vont permettre de choisir précisément la classe à prendr e en compte avec le nom de la balise associée. Ainsi, lorsque n ous placerons uneforme, le système proposera la balise correspondante parmi celles qui font partie de l'ensemble défini par l'annotatio n @XmlElements .

L'attribut name de l'annotation @XmlElement permet d'indiquer le nom de la balise dans le document XML.

L'attribut type de l'annotation @XmlElement permet d'indiquer le nom de la classe associée.

4. Et c'est tout . . . Finalement, nous utilisons très très peu d'annotations.

Codage de l'applicationprincipale

Page 15: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

package jaxb ;

import java.awt .*;import java.awt .event.*;import java. io .File ;import javax .swing .*;import javax .xml .bind .*;import jaxb .Formes .*;

public class Principal extends JFrame { private Tracé dessins = new Tracé() ; private JRadioButton cercle = new JRadioButton ("Cercle" , true ); private JRadioButton carré = new JRadioButton ("Carré" ); private JFormattedTextField largeur = new JFormattedTextField (50); private ButtonGroup groupe = new ButtonGroup (); private JPanel boutons = new JPanel (); private JToolBar barre = new JToolBar ();

public Principal() { super ("Tracé de formes" ); add(barre , BorderLayout.NORTH ); barre .add(new AbstractAction ("Nouveau" , new ImageIcon ("nouveau.gif" )) { public void actionPerformed (ActionEvent e) { dessins .effacer() ; } }); barre .add(new AbstractAction ("Ouvrir" , new ImageIcon ("ouvrir.gif" )) { public void actionPerformed (ActionEvent e) { dessins .ouvrir() ; } }); barre .add(new AbstractAction ("Enregistrer" , new ImageIcon ("enregistrer.gif" )) { public void actionPerformed (ActionEvent e) { dessins .enregistrer() ; } }); dessins .addMouseListener (new MouseAdapter () { @Override public void mouseClicked (MouseEvent e) { int larg = (Integer )largeur .getValue(); if (cercle . isSelected ()) dessins .ajoutForme (new Cercle(e.getX(), e.getY(), larg/2)); else dessins .ajoutForme (new Carré(e.getX(), e.getY(), larg)); } }); add(dessins ); largeur .setColumns (3); boutons .add(cercle ); boutons .add(carré ); boutons .add(largeur ); groupe .add(cercle ); groupe .add(carré ); add(boutons , BorderLayout.SOUTH ); setSize (400, 300); setLocationRelativeTo (null ); setDefaultCloseOperation (EXIT_ON_CLOSE); setVisible (true ); }

public static void main(String [] args ) { new Principal(); }

private class Tracé extends JComponent { private Formes formes = new Formes(); private Marshaller mapperObjetsXML ; private Unmarshaller mapperXMLObjets ; public Tracé() { try { JAXBContext contexte = JAXBContext .newInstance (Formes .class ); mapperObjetsXML = contexte .createMarshaller() ; mapperObjetsXML .setProperty (Marshaller .JAXB_FORMATTED_OUTPUT, true); mapperXMLObjets = contexte .createUnmarshaller() ; } catch (JAXBException ex) { setTitle ("Impossible de créer le document XML" ); } }

@Override protected void paintComponent (Graphics g) { super .paintComponent (g); Graphics2D surface = (Graphics2D ) g; surface .setStroke (new BasicStroke (5)); surface .setRenderingHint (RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON ); if (formes !=null) for (Forme forme : formes .getFormes() ) forme .dessine (surface ); }

public void effacer() { formes .supprimerFormes() ; revalidate (); repaint (); }

public void ajoutForme (Forme forme ) { formes .ajoutForme (forme ); repaint (); }

private void enregistrer() {

Page 16: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

try { mapperObjetsXML .marshal (formes , new File ("Formes.xml" )); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } }

private void ouvrir() { try { formes = (Formes) mapperXMLObjets .unmarshal (new File ("Formes.xml" )); repaint (); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } } }}

Vous remarquez ici, par rapport aux chapitres précédents, q ue la gestion des formes est beaucoup plus simple, puisqu'il s'agit de classes des plus normalessans annotations particulières. Le fait d'avoir d'ailleur s une classe abstraite commune permet de simplifier encore p lus le problème.

L'utilisation des annotations sans passer par une Schéma XM L me paraît finalement plus facile à mettre en oeuvre et surto ut plus intuitif. L'intérêt du SchémaXML est surtout intéressant lorsque nous devons faire une ap plication qui tient compte de documents XML déjà existants.

Quelquesconsidérationstechniquessur certainesannotations

Le tableau ci-dessous reprend quelques-unes des annotatio ns pour bien préciser leur particularité et leur utilité.

Annotation Considérations

XmlRootElement Peut être utilisée sur une classe pour préciser que cette cla sse sera l 'élément racine du document XML. Chaque attribut d e la classedevient ainsi un élément fils dans le document XML. L'attrib ut namespace de l 'annotation @XmlRootElement permet de préciserl 'espace de nommage.

Codage de la classe Personne qui va servir de référence

import java .util .Date; import javax .xml .bind .annotation .*; @XmlRootElement public class Personne { private String nom ; private String prenom ; private int taille ; private Date dateNaissance ; public Personne() { } public Personne (String nom , String prenom , int taille , Date dateNaissance ) { super (); this .nom = nom ; this .prenom = prenom ; this .taille = taille ; this .dateNaissance = dateNaissance ; } public Date getDateNaissance() { return dateNaissance ; } public void setDateNaissance (Date dateNaissance ) { this .dateNaissance = dateNaissance ; } public String getNom() { return nom ; } public void setNom (String nom ) { this .nom = nom ; } public String getPrenom() { return prenom ; } public void setPrenom (String prenom ) { this .prenom = prenom ; } public int getTaille() { return taille ; } public void setTaille (int taille ) { this .taille = taille ; } }

Résultat

<?xml version ="1.0" encoding ="UTF-8" standalone ="yes" ?> <personne> <nom> REMY</nom> <prenom> Emmanuel </prenom> <taille> 171</ taille>

Page 17: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

<dateNaissance> 2007-01-16T17:03:31.213+01:00 </dateNaissance></personne>

XmlTransient Permet d'ignorer une propriété/entité dans la mapping entre l 'objet et l 'élément XML correspondan t :

Exemple

import java .util .Date; import javax .xml .bind .annotation .*; @XmlRootElement public class Personne { . . . @XmlTransient public String getNom() { return nom ; } . . .}

Résultat

<?xml version ="1.0" encoding ="UTF-8" standalone ="yes" ?> <personne> <prenom> Emmanuel </prenom> <taille> 171</ taille> <dateNaissance> 2007-01-16T17:03:31.213+01:00 </dateNaissance></personne>

XmlAttribute Permet de mapper une propriété sous la forme d'un attribut et fournir des précisions sur la configuration de cet attribut

Exemple

import java .util .Date; import javax .xml .bind .annotation .*; @XmlRootElement public class Personne { . . . @XmlAttribute public String getNom() { return nom ; } . . .}

Résultat

<?xml version ="1.0" encoding ="UTF-8" standalone ="yes" ?> <personne nom ="REMY" > <prenom> Emmanuel </prenom> <taille> 171</ taille> <dateNaissance> 2007-01-16T17:03:31.213+01:00 </dateNaissance></personne>

XmlElementWrapper Pour les collections, il est possible d'utiliser l 'annotat ion @XmlElementWrapper pour définir un élement père qui encapsule lesoccurrences de la collection et d'utiliser l 'annotation @XmlElement pour préciser le nom de chaque élément de la collection.

Exemple

import java .util .Date; import javax .xml .bind .annotation .*; @XmlRootElement public class Personne { private String nom ; private String prenom ; private int taille ; private Date dateNaissance ; @XmlElementWrapper (name = "Residence" ) @XmlElement (name = "Adresse" ) protected List< Adresse > adresses = new ArrayList< Adresse >(); . . . }

class Adresse { private String rue; private int codePostal; private String ville; private String pays;. . .}

Résultat

<?xml version ="1.0" encoding ="UTF-8" standalone ="yes" ?> <personne> <nom> REMY</nom> <prenom> Emmanuel </prenom> <taille> 171</ taille> <dateNaissance> 2007-01-16T17:03:31.213+01:00 </dateNaissance> <Residence> <Adresse> <rue> Nom de la rue </rue> <codePostal> 78895</codePostal> <ville> Une ville </ville> <pays> France</pays> </Adresse>

Page 18: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

</Residence></personne>

XmlType Il est possible de configurer l 'ordre des éléments au traver s de cette annotation

Exemple

import java .util .Date; import javax .xml .bind .annotation .*; @XmlRootElement @XmlType(propOrder = {"dateNaissance", "adresses", "nom", "prenom", "tai lle"} ) public class Personne { private String nom ; private String prenom ; private int taille ; private Date dateNaissance ; @XmlElementWrapper (name = "Residence" ) @XmlElement (name = "Adresse" ) protected List< Adresse > adresses = new ArrayList< Adresse >(); . . . }

class Adresse { private String rue; private int codePostal; private String ville; private String pays;. . .}

Résultat

<?xml version ="1.0" encoding ="UTF-8" standalone ="yes" ?> <personne> <dateNaissance> 2007-01-16T17:03:31.213+01:00 </dateNaissance> <Residence> <Adresse> <rue> Nom de la rue </rue> <codePostal> 78895</codePostal> <ville> Une ville </ville> <pays> France</pays> </Adresse> </Residence> <nom> REMY</nom> <prenom> Emmanuel </prenom> <taille> 171</ taille> </personne>

XmlJavaTypeAdapter Il est possible de définir des classes de type Adapter qui permettent de personnaliser la façon dont un objet est serialisé/desérialisédans le document XML. Ces classes Adapter héritent de la classe javax.xml.bind.annotation.adapters.XmlAdapter . Il suffit de redéfinirles méthodes marshal() et unmashal() afin de permettre un formatage de l 'information adapté au vi suel que nous désirons faireapparaître côté document XML. Ces méthodes seront automati quement utilisées à l 'exécution par l 'API JAXB lors des tran sformations.L'annotation @XmlJavaTypeAdapter permet de préciser la classe de type Adapter qui sera à utiliser plutôt que d'utiliser la conversionpar défaut

Exemple

import java .util .Date; import java.text. *; import javax .xml .bind .annotation .*;import javax.xml.bind.annotation.adapters.*; @XmlRootElement @XmlType(propOrder = {"dateNaissance", "adresses", "nom", "prenom", "tai lle"} ) public class Personne { private String nom ; private String prenom ; private int taille ; @XmlJavaTypeAdapter (DateAdapter .class) private Date dateNaissance ; @XmlElementWrapper (name = "Residence" ) @XmlElement (name = "Adresse" ) protected List< Adresse > adresses = new ArrayList< Adresse >(); . . . }

class Adresse { private String rue; private int codePostal; private String ville; private String pays;. . .}

class DateAdapter extends XmlAdapter< String , Date> { private DateFormat miseEnForme = DateFormat .getDateInstance( DateFormat.LONG );

public Date unmarshal (String date) throws Exception { return miseEnForme .parse (date); }

public String marshal (Date date) throws Exception { return miseEnForme . format (date); } }

Résultat

Page 19: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

<?xml version ="1.0" encoding ="UTF-8" standalone ="yes" ?> <personne> <dateNaissance> 1 octobre 1959 </dateNaissance> <Residence> <Adresse> <rue> Nom de la rue </rue> <codePostal> 78895</codePostal> <ville> Une ville </ville> <pays> France</pays> </Adresse> </Residence> <nom> REMY</nom> <prenom> Emmanuel </prenom> <taille> 171</ taille> </personne>

Deuxièmeexemplede mise en oeuvre- Miseen placed'attributsdans les balisesXML

Nous allons reprendre l'application précédente qui permet de sauvegarder, et donc de restituer un ensemble de formes, d ans un document XML. Ce document XMLest légèrement différent que le précédent. Pour chacune des formes, nous envisageons, cette fois-ci , de prendre une nou velle balise nommée <centre> à l'intérieurde laquelle nous stipulons les coordonnées du centre de la fo rme.

Cette fois-ci nous devons proposer des attributs, respecti vement x et y , qui vont représenter les coordonnées dela balise <centre> .

Mise en place du sourcerelatif aux formes

package jaxb ;

import java.awt .Graphics2D ;import java.util .ArrayList ;import javax .xml .bind .annotation .*;

/ / Définition de l 'élément racine du document et de ses sous-éléments@XmlRootElementpublic class Formes { @XmlElements ({ @XmlElement (name = "carré" , type = Carré.class ), @XmlElement (name = "cercle" , type = Cercle.class ) }) private ArrayList <Forme> formes = new ArrayList <Forme>();

public ArrayList <Forme> getFormes() { return formes ; } public void ajoutForme (Forme forme ) { formes .add(forme ); } public void supprimerFormes () { formes .clear (); }}

/ / La classe Forme est modifiée pour accueillir un centre à la place des coordonnées x et yabstract class Forme { protected Centre centre ; public Forme() { centre = new Centre(); } public Forme(int x , int y ) { centre = new Centre(x , y ); } public Centre getCentre() { return centre ; } public void setCentre (Centre centre ) { this .centre = centre ; } abstract void dessine (Graphics2D surface );}

/ / Nouvel élément représenant le <centre> qui possède deux attributs x et yclass Centre { @XmlAttribute private int y ; @XmlAttribute private int x ;

public Centre() {} public Centre(int x , int y ) { this .x = x ; this .y = y ; } public int getX() { return x ; } public int getY() { return y ; } }

class Cercle extends Forme { private int rayon = 50; public Cercle() {} public Cercle(int x , int y , int rayon ) { super (x , y ); this .rayon = rayon ; } public int getRayon() { return rayon ; } public void setRayon (int rayon ) { this . rayon = rayon ; }

Page 20: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

@Override void dessine (Graphics2D surface ) { int x = centre .getX() ; int y = centre .getY() ; surface .drawOval (x -rayon , y -rayon , 2*rayon , 2*rayon ); }}

class Carré extends Forme { private int côté = 100; public Carré() {} public Carré(int x , int y , int côté ) { super (x , y ); this .côté = côté ; } public int getCôté() { return côté ; } public void setCôté (int côté ) { this .côté = côté ; } @Override void dessine (Graphics2D surface ) { int x = centre .getX() ; int y = centre .getY() ; surface .drawRect (x -côté /2, y -côté /2, côté , côté ); }}

Dans ce source, nous pouvons faire un certain nombrede remarques:

1. La plus grosse partie du code n'est pas modifiée.

2. Nous devons mettre en oeuvre une classe Centre qui, dès lors, possède les coordonnées des formes souhaitée s. Les coordonnées deviennent alors desattributs XML de cette classe Centre.

3. Dans la classe Forme, nous proposons un nouvel attribut centre , de type Centre, qui remplace les attributs x et y . Les constructeurs doivent prendre encompte la création de ces différents centres.

4. Il faut revoir également les méthodes redéfinies dessine() puisque nous ne pouvons plus accéder directement aux coordo nnées.

5. Encore une fois, malgrès un changement notable sur le docu ment XML, nous utilisons très peu d'annotations.

Répertoiretéléphoniqueavecune MAP

Cette fois-ci , nous changeons de sujet. Nous proposons une a pplication qui permet de stocker un petit répertoire téléph onique de portable associé juste à quelquesprénoms connus. Ce répertoire devra toutefois être dans l'o rdre alphabétique des prénoms.

Sourcedu répertoiretéléphonique

package carte;

import java.awt .*;import java.awt .event.ActionEvent ;import java. io .File ;import java. text .ParseException ;import javax .swing .*;import java.util . *;import javax .swing . text .MaskFormatter ;import javax .xml .bind .*;import javax .xml .bind .annotation .*;

public class GestionRépertoire extends JFrame { private JTextField prénom = new JTextField ("Nouveau prénom" , 18); private JFormattedTextField téléphone ; private JPanel panneau = new JPanel (); private JToolBar barre = new JToolBar (); private Marshaller mapperObjetsXML ; private Unmarshaller mapperXMLObjets ; private Répertoire répertoire = new Répertoire() ; private JComboBox liste = new JComboBox ();

public GestionRépertoire() throws ParseException { super ("Répertoire téléphonique" ); documentXML(); liste .setForeground (Color.RED ); téléphone = new JFormattedTextField (new MaskFormatter ("##-##-##-##-##" )); téléphone .setValue ("06-00-00-00-00" ); barre .add(new AbstractAction ("Ajout" ) { public void actionPerformed (ActionEvent e) { répertoire .ajout (prénom .getText (), (String ) téléphone .getValue()); répertoire .miseAJour (liste ); } }); barre .add(new AbstractAction ("Suppression" ) {

Page 21: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

public void actionPerformed (ActionEvent e) { répertoire .suppression (prénom .getText ()); répertoire .miseAJour (liste ); } }); barre .add(new AbstractAction ("Ouvrir" , new ImageIcon ("ouvrir.gif" )) { public void actionPerformed (ActionEvent e) { try { répertoire = (Répertoire ) mapperXMLObjets .unmarshal (new File ("Téléphones.xml" )); répertoire .miseAJour (liste ); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } } }); barre .add(new AbstractAction ("Enregistrer" , new ImageIcon ("enregistrer.gif" )) { public void actionPerformed (ActionEvent e) { try { mapperObjetsXML .marshal (répertoire , new File ("Téléphones.xml" )); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } } }); add(barre , BorderLayout.NORTH ); panneau .add(new JLabel ("Prénom : " )); panneau .add(prénom ); panneau .add(new JLabel ("Téléphone : " )); panneau .add(téléphone ); add(panneau ); add(liste , BorderLayout.SOUTH ); pack (); setLocationRelativeTo (null ); setResizable (false ); setDefaultCloseOperation (EXIT_ON_CLOSE); setVisible (true ); }

private void documentXML() { try { JAXBContext contexte = JAXBContext .newInstance (Répertoire .class ); mapperObjetsXML = contexte .createMarshaller (); mapperObjetsXML .setProperty (Marshaller .JAXB_FORMATTED_OUTPUT, true); mapperXMLObjets = contexte .createUnmarshaller (); } catch (JAXBException ex) { setTitle ("Impossible de créer le document XML" ); } } public static void main(String [] args ) throws ParseException { new GestionRépertoire() ; }}

@XmlRootElementclass Répertoire { private TreeMap<String , String > répertoire = new TreeMap<String , String >();

public TreeMap<String , String > getRépertoire() { return répertoire ; } public void setRépertoire (TreeMap<String , String > répertoire ) { this .répertoire = répertoire ; }

public void ajout (String prénom , String numéro ) { répertoire .put (prénom , numéro ); } public void suppression (String prénom ) { répertoire . remove (prénom ); } public void miseAJour (JComboBox liste ) { liste .removeAllItems (); for (Map.Entry <String , String > élément : répertoire .entrySet() ) liste .addItem (élément ); }}

Faisons un certain nombrede remarques:

1. La classe utilisée pour stocker l'ensemble des numéros es t la classe TreeMap qui permet de gérer dans l'ordre ce que nous appelons des cart es.

2. Nous plaçons juste une annotation @XmlRootElement qui permet de gérer l'ensemble des numéros au travers de ce Map.

3. Tout ce fait automatiquement.

4. L'inconvénient toutefois, c'est que le nom des balises, d ans le document XML, est alors imposé. Nous trouvons donc des intitulés correspondant à laterminologie utilisée par l'interface Map, c'est-à-dire : <entry> , <key> et <value> .

5. Il sera éventuellement nécessaire de passer par une class e de type Adapter pour contrôler le nom des balises du document XML.

Répertoiretéléphoniqueavecune MAPet une classed'adaptationpourle documentXML

Nous reprenons le même sujet que précédemment. L'objectif i ci est de proposer une meilleure mise en forme du document XML pour une lecture plus adaptée à lasituation.

Partie du code sur la mise en forme du documentXML uniquement

Page 22: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

. . .@XmlRootElementclass Répertoire { @XmlElement (name ="téléphones" ) @XmlJavaTypeAdapter (MapAdapter .class ) private TreeMap<String , String > répertoire = new TreeMap<String , String >();

public TreeMap<String , String > getRépertoire() { return répertoire ; } public void ajout (String prénom , String numéro ) { répertoire .put (prénom , numéro ); } public void suppression (String prénom ) { répertoire . remove (prénom ); } public void miseAJour (JComboBox liste ) { liste .removeAllItems (); for (Map.Entry <String , String > élément : répertoire .entrySet ()) liste .addItem (élément ); }}

class MapAdapter extends XmlAdapter <Téléphones , TreeMap<String , String >> { @Override public TreeMap<String , String > unmarshal (Téléphones téléphones ) throws Exception { TreeMap<String , String > cartes = new TreeMap<String , String >(); for (Téléphone téléphone : téléphones .getTéléphones() ) cartes .put (téléphone .getPrénom() , téléphone .getNuméro() ); return cartes ; } @Override public Téléphones marshal (TreeMap<String , String > valeurs ) throws Exception { Téléphones téléphones = new Téléphones() ; for (Map.Entry <String , String > carte : valeurs .entrySet() ) téléphones .getTéléphones() .add(new Téléphone (carte.getKey (), carte.getValue())); return téléphones ; }}

class Téléphones { @XmlElement (name ="téléphone" ) private ArrayList <Téléphone > téléphones = new ArrayList <Téléphone >(); public ArrayList <Téléphone > getTéléphones() { return téléphones ; }}class Téléphone { @XmlAttribute private String numéro ; @XmlAttribute private String prénom ;

public String getNuméro() { return numéro ; } public String getPrénom() { return prénom ; }

public Téléphone (String prénom , String numéro ) { this .prénom = prénom ; this .numéro = numéro ; }

public Téléphone() {}}

Faisons un certain nombrede remarques:

1. Il n'existe pas d'annotation spécifiques à un conteneur d e type Map. Nous devons donc tout construire pour avoir un document XML suivant notre souhait.

2. Dans notre document XML, pour nommer un élément <téléphone> , nous devons utiliser spécifiquement l'annotation @XmlElement . Or, cette annotation nese place qu'au dessus d'une propriété de classe. La seule sol ution consiste donc à créer une classe conteneur qui possède alors une liste d'éléments.Ainsi chaque élément sera bien nommé <téléphone> , si le choix de l'attribut de la classe porte le même nom où si n ous spécifions le nom au travers del'attribut name de l'annotation @XmlElement .

3. Pour avoir des attributs sur cette balise <téléphone> , nous devons créer également une classe dont chacune des pro priétés aura comme annotation @XmlAttribute . Ici aussi, les attributs d'une balise correspondent toujo urs aux attributs d'une classe. La création de cette classe d evient donc obligatoire.Finalement la liste précédente sera une liste de cette class e.

4. Pour finir, il faut faire le lien entre la Map (liaison avec le programme principal) et la liste (liaison avec le document UML). La seule solution est de prop oserune classe Adapter qui fait le marshalling et l' unmarshalling de façon adéquat.

Répertoiretéléphoniquepouvantintégrerplusieurstéléphones

Nous reprenons de nouveau la même application. Chaque utili sateur peut cette fois-ci avoir plusieurs téléphones : le mo bile, le téléphone du domicile ou letéléphone du travail.

Page 23: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

Sourcecomplet

package carte;

import java.awt .*;import java.awt .event.ActionEvent ;import java. io .File ;import java. text .ParseException ;import javax .swing .*;import java.util . *;import javax .swing . text .MaskFormatter ;import javax .xml .bind .*;import javax .xml .bind .annotation .*;import javax .xml .bind .annotation .adapters .*;

public class GestionRépertoire extends JFrame { private JTextField prénom = new JTextField ("Nouveau prénom" , 18); private JFormattedTextField téléphone ; private JPanel panneau = new JPanel (); private JToolBar barre = new JToolBar (); private Marshaller mapperObjetsXML ; private Unmarshaller mapperXMLObjets ; private Répertoire répertoire = new Répertoire() ; private JComboBox typeTéléphone = new JComboBox (TypeTéléphone .values() ); private JComboBox liste = new JComboBox ();

public GestionRépertoire() throws ParseException { super ("Répertoire téléphonique" ); documentXML(); liste .setForeground (Color .RED); téléphone = new JFormattedTextField (new MaskFormatter ("##-##-##-##-##" )); téléphone .setValue ("06-00-00-00-00" ); barre .add(new AbstractAction ("Ajout" ) { public void actionPerformed (ActionEvent e) { répertoire .ajout (prénom .getText (), typeTéléphone .getSelectedItem (), (String ) téléphone .getValue()); répertoire .miseAJour (liste ); } }); barre .add(new AbstractAction ("Suppression" ) { public void actionPerformed (ActionEvent e) { répertoire .suppression (prénom .getText ()); répertoire .miseAJour (liste ); } }); barre .add(new AbstractAction ("Ouvrir" , new ImageIcon ("ouvrir.gif" )) { public void actionPerformed (ActionEvent e) { try { répertoire = (Répertoire ) mapperXMLObjets .unmarshal (new File ("Téléphones.xml" )); répertoire .miseAJour (liste ); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } } }); barre .add(new AbstractAction ("Enregistrer" , new ImageIcon ("enregistrer.gif" )) { public void actionPerformed (ActionEvent e) { try { mapperObjetsXML .marshal (répertoire , new File ("Téléphones.xml" )); } catch (JAXBException ex) { setTitle ("Impossible d'enregistrer le document XML" ); } } }); add(barre , BorderLayout.NORTH ); panneau .add(new JLabel ("Prénom : " )); panneau .add(prénom ); panneau .add(new JLabel ("Téléphone : " )); panneau .add(typeTéléphone ); panneau .add(téléphone ); add(panneau ); add(liste , BorderLayout.SOUTH ); pack (); setLocationRelativeTo (null ); setResizable (false ); setDefaultCloseOperation (EXIT_ON_CLOSE); setVisible (true ); }

private void documentXML() {

Page 24: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

try { JAXBContext contexte = JAXBContext .newInstance (Répertoire .class ); mapperObjetsXML = contexte .createMarshaller(); mapperObjetsXML .setProperty (Marshaller .JAXB_FORMATTED_OUTPUT, true); mapperXMLObjets = contexte .createUnmarshaller() ; } catch (JAXBException ex) { setTitle ("Impossible de créer le document XML" ); } }

public static void main(String [] args ) throws ParseException { new GestionRépertoire (); }}

enum TypeTéléphone {Mobile , Domicile , Travail };

@XmlRootElementclass Répertoire { @XmlElement (name ="téléphones" ) @XmlJavaTypeAdapter (MapAdapter .class ) private TreeMap<String , EnumMap <TypeTéléphone , String >> répertoire = new TreeMap<String , EnumMap <TypeTéléphone , String >>();

public TreeMap<String , EnumMap <TypeTéléphone , String >> getRépertoire() { return répertoire ; } public void suppression (String prénom ) { répertoire . remove (prénom ); }

public void ajout (String prénom , Object type , String numéro ) { EnumMap <TypeTéléphone , String > téléphones ; if (répertoire .containsKey (prénom )) { téléphones = répertoire .get(prénom ); téléphones .put ((TypeTéléphone )type , numéro ); } else { téléphones = new EnumMap <TypeTéléphone , String >(TypeTéléphone .class ); téléphones .put ((TypeTéléphone )type , numéro ); répertoire .put (prénom , téléphones ); } }

public void miseAJour (JComboBox liste ) { liste .removeAllItems (); for (Map.Entry <String , EnumMap <TypeTéléphone , String >> carte : répertoire .entrySet ()) liste .addItem (carte); }}

class MapAdapter extends XmlAdapter <Téléphones , TreeMap<String , EnumMap <TypeTéléphone , String >>> { @Override public TreeMap< String , EnumMap<TypeTéléphone, String >> unmarshal (Téléphones téléphones ) throws Exception { TreeMap< String , EnumMap<TypeTéléphone, String >> cartes = new TreeMap< String , EnumMap<TypeTéléphone, String >>(); for (Téléphone téléphone : téléphones .getTéléphones() ) { EnumMap <TypeTéléphone , String > liste = new EnumMap <TypeTéléphone , String >(TypeTéléphone .class ); for (NuméroParType npt : téléphone .getTéléphone() ) liste .put (npt .getType() , npt .getNuméro() ); cartes .put (téléphone .getPrénom() , liste ); } return cartes ; } @Override public Téléphones marshal (TreeMap< String , EnumMap<TypeTéléphone, String >> valeurs ) throws Exception { Téléphones téléphones = new Téléphones() ; for (Map.Entry <String , EnumMap <TypeTéléphone , String >> carte : valeurs .entrySet ()) { Téléphone personne = new Téléphone (carte.getKey ()); for (Map.Entry <TypeTéléphone , String > téléphone : carte.getValue().entrySet ()) personne .ajoutTéléphone (téléphone .getKey (), téléphone .getValue()); téléphones .getTéléphones() .add(personne ); } return téléphones ; }}

class Téléphones { @XmlElement (name ="personne" ) private ArrayList <Téléphone > téléphones = new ArrayList <Téléphone >(); public ArrayList <Téléphone > getTéléphones() { return téléphones ; }}

class Téléphone { @XmlAttribute private String prénom ; @XmlElement private ArrayList <NuméroParType > téléphone = new ArrayList <NuméroParType >();

public Téléphone (String prénom ) { this .prénom = prénom ; } public Téléphone() {}

public String getPrénom() { return prénom ; } public ArrayList <NuméroParType > getTéléphone() { return téléphone ; }

public void ajoutTéléphone (TypeTéléphone type , String numéro ) { téléphone .add(new NuméroParType (type, numéro )); }}

class NuméroParType { @XmlAttribute private String numéro ; @XmlAttribute private TypeTéléphone type ;

Page 25: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

public NuméroParType() {} public NuméroParType (TypeTéléphone type , String numéro ) { this . type = type ; this .numéro = numéro ; }

public String getNuméro() { return numéro ; } public TypeTéléphone getType() { return type ; }}

Il existe une annotation @XmlEnum , mais vous remarquez qu'il n'a pas été nécessaire de la mettr e en oeuvre. JAXB se débrouille très bien sans et proposeles énumérateurs sous forme de chaînes de caractères, ceci a utomatiquement.

Générer un schéma à partir de classes compilées

L'outil schemagen fourni avec l'implémentation par défaut permet de générer u n schéma XML à partir de classes annotées compilées.

Exempled'applicationqui va servirde basepourla créationd'un schémaXML

Nous allons reprendre l'application du tracé de formes qui p ermet de sauvegarder, et donc de restituer un ensemble de for mes, dans un document XML.

Cette fois-ci nous devons proposer des attributs, respecti vement x et y , qui vont représenter les coordonnées dela balise <centre> .

Mise en place du sourcerelatif aux formes

package jaxb ;

import java.awt .Graphics2D ;import java.util .ArrayList ;import javax .xml .bind .annotation .*;

/ / Définition de l 'élément racine du document et de ses sous-éléments@XmlRootElementpublic class Formes { @XmlElements ({ @XmlElement (name = "carré" , type = Carré.class ), @XmlElement (name = "cercle" , type = Cercle.class ) }) private ArrayList <Forme> formes = new ArrayList <Forme>();

public ArrayList <Forme> getFormes() { return formes ; } public void ajoutForme (Forme forme ) { formes .add(forme ); } public void supprimerFormes () { formes .clear (); }}

/ / La classe Forme est modifiée pour accueillir un centre à la place des coordonnées x et yabstract class Forme { protected Centre centre ; public Forme() { centre = new Centre(); } public Forme(int x , int y ) { centre = new Centre(x , y ); } public Centre getCentre() { return centre ; } public void setCentre (Centre centre ) { this .centre = centre ; } abstract void dessine (Graphics2D surface );}

/ / Nouvel élément représenant le <centre> qui possède deux attributs x et yclass Centre { @XmlAttribute private int y ; @XmlAttribute private int x ;

public Centre() {} public Centre(int x , int y ) { this .x = x ; this .y = y ; } public int getX() { return x ; } public int getY() { return y ; } }

class Cercle extends Forme { private int rayon = 50; public Cercle() {} public Cercle(int x , int y , int rayon ) { super (x , y ); this .rayon = rayon ; } public int getRayon() { return rayon ; } public void setRayon (int rayon ) { this . rayon = rayon ; }

Page 26: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

@Override void dessine (Graphics2D surface ) { int x = centre .getX() ; int y = centre .getY() ; surface .drawOval (x -rayon , y -rayon , 2*rayon , 2*rayon ); }}

class Carré extends Forme { private int côté = 100; public Carré() {} public Carré(int x , int y , int côté ) { super (x , y ); this .côté = côté ; } public int getCôté() { return côté ; } public void setCôté (int côté ) { this .côté = côté ; } @Override void dessine (Graphics2D surface ) { int x = centre .getX() ; int y = centre .getY() ; surface .drawRect (x -côté /2, y -côté /2, côté , côté ); }}

Utilisationde l'utilitaireschemagen

Schema1.xsd

Page 27: Java et XML - JAXBprogrammation-java.1sur1.com/Java/Tutoriels/TechniquesSup/PDF/JAX… · JAXB JAXB est l'acronyme de Java Architecture for XML Binding. Le but de l'API et des spécifications

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xs:schema version ="1.0" xmlns:xs ="http:/ /www.w3.org/2001/XMLSchema" >

<xs:element name ="formes" type="formes" />

<xs:complexType name ="formes" > <xs:sequence> <xs:choice minOccurs ="0" maxOccurs ="unbounded" > <xs:element name ="carr &#233; " type="carr &#233; " /> <xs:element name ="cercle" type="cercle" /> </xs:choice> </xs:sequence> </xs:complexType>

<xs:complexType name ="carr &#233; "> <xs:complexContent> <xs:extension base="forme" > <xs:sequence> <xs:element name ="c &#244; t&#233; " type="xs:int" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>

<xs:complexType name ="forme" abstract ="true" > <xs:sequence> <xs:element name ="centre" type="centre" minOccurs ="0" /> </xs:sequence> </xs:complexType>

<xs:complexType name ="centre" > <xs:sequence/> <xs:attribute name ="x" type="xs:int" use="required" /> <xs:attribute name ="y" type="xs:int" use="required" /> </xs:complexType>

<xs:complexType name ="cercle" > <xs:complexContent> <xs:extension base="forme" > <xs:sequence> <xs:element name ="rayon" type="xs:int" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType></xs:schema>