"Pas si vite, jeune homme ! J'ai encore deux leçons pour toi !"

"Deux ? Wow. Eh bien, d'accord. Que ne feriez-vous pas pour améliorer votre propre sang-froid ! Je suis tout ouïe."

"XML, comme JSON, est souvent utilisé pour transmettre des données entre différents programmes et ordinateurs. Et il existe plusieurs frameworks qui simplifient grandement la vie des programmeurs Java lorsqu'ils travaillent avec XML. Aujourd'hui, je vais vous présenter l'un d'entre eux."

"JAXB est un excellent framework polyvalent pour travailler avec XML."

JAXB - 1

"JAXB fait partie du JDK, vous n'avez donc pas besoin de le télécharger séparément."

"Laissez-moi d'abord vous montrer un exemple d'utilisation, puis nous l'analyserons. Par exemple :"

Convertir un objet en XML
public static void main(String[] args) throws JAXBException
{
 // Create an object to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // And here's the serialization itself:
 marshaller.marshal(cat, writer);

 // Convert everything written to the StringWriter
 String result = writer.toString();
 System.out.println(result);
}
Une classe dont les objets sont convertis en XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
Résultat de sérialisation et sortie d'écran :
<cat> 
<name> Missy </name> 
<age> 5 </age> 
<weight> 4 </weight> 
</cat>

"Pour une raison quelconque, ligne par ligne, ce code me rappelle la sérialisation JSON. Les mêmes annotations, mais JSON a utilisé un ObjectMapper, et cela utilise Context et Marshaller."

"Ouais. Ils sont vraiment très similaires. Jackson a été calqué sur JAXB. Mais JAXB a également été copié quelque part. Vous ne pouvez pas inventer quelque chose de génial à partir de zéro."

"Cela semble être le cas."

"OK, voici ce qui se passe :"

"Dans les lignes 4 à 7, nous créons un objet Cat et le remplissons avec des données."

"À la ligne 10, nous créons un objet Writer pour écrire le résultat."

"À la ligne 13, nous créons le" contexte ". Ceci est similaire à ObjectMapper, mais deux objets enfants supplémentaires sont créés à partir de celui-ci. Marshaller est pour la sérialisation et Unmarshaller est pour la désérialisation. Il y a de petites différences par rapport à Jackson, mais ce n'est pas le cas. ce n'est pas fondamentalement différent."

"À la ligne 14, nous créons un objet Marshaller . Marshalling est synonyme de sérialisation."

"À la ligne 15, nous définissons la propriété FORMATTED_OUTPUT sur TRUE. Cela ajoutera des sauts de ligne et des espaces au résultat, de sorte que le code soit lisible par l'homme et n'ait pas simplement tout le texte sur une seule ligne."

"À la ligne 17, nous sérialisons l'objet."

"Dans les lignes 20-21, nous affichons le résultat de la sérialisation à l'écran."

"Que sont les annotations @XmlType(name = 'cat&') et @XmlRootElement ?"

" @XmlRootElement indique que cet objet peut être la 'racine d'un arbre' d'éléments XML. En d'autres termes, il peut s'agir de l'élément de plus haut niveau et peut contenir tous les autres éléments."

" @XmlType(name = 'cat') indique que la classe est impliquée dans la sérialisation JAXB et spécifie également le nom de la balise XML pour cette classe."

"D'accord, je vais maintenant vous montrer un exemple de désérialisation XML :"

Convertir un objet à partir de XML
public static void main(String[] args) throws JAXBException
{
 String xmldata = "<cat><name>Missy</name><age>5</age><weight>4</weight></cat>";
 StringReader reader = new StringReader(xmldata);

 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Unmarshaller unmarshaller = context.createUnmarshaller();

 Cat cat = (Cat) unmarshaller.unmarshal(reader);
}
Une classe dont les objets sont désérialisés à partir de XML
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"Tout est presque pareil qu'avec Jackson. Mais juste au cas où, je vais t'expliquer tout ce qui se passe ici."

"À la ligne 3, nous passons une chaîne qui stocke le XML à désérialiser."

"À la ligne 4, nous encapsulons la chaîne XML dans un StringReader ."

"A la ligne 6, on crée un contexte JAXB , auquel on passe la liste des classes."

"À la ligne 7, nous créons un Unmarshaller - l'objet qui effectuera la désérialisation."

"À la ligne 9, nous désérialisons le XML de l'objet lecteur et obtenons un objet Cat."

"Maintenant, tout semble presque évident. Mais il y a quelques heures, je me creusais la tête pour comprendre comment cela fonctionnait."

"Cela se produit toujours lorsque vous devenez plus intelligent. Les choses complexes deviennent simples."

"Je deviens plus intelligent? Je ne peux pas m'empêcher d'être heureux à ce sujet."

"Génial. Alors voici une liste d'annotations que vous pouvez utiliser pour contrôler le résultat de la sérialisation JAXB :"

Annotations JAXB Description
@XmlElement(nom) Placé près d'un champ.
Le champ sera stocké dans un élément XML.
Permet de définir le nom de la balise.
@XmlAttribute(nom) Placé près d'un champ.
Le champ sera stocké en tant qu'attribut XML !
Permet de définir le nom de l'attribut.
@XmlElementWrapper(nillable = true) Placé près d'un champ.
Vous permet de définir une 'balise wrapper' pour un groupe d'éléments.
@XmlType Placé près d'une classe.
Vous permet de spécifier une méthode pour créer un objet si le constructeur par défaut est privé.
@XmlJavaTypeAdapter Placé près d'un champ.
Permet de spécifier la classe qui convertira le champ en chaîne.

« Comme c'est intéressant ! Mais pouvez-vous me donner un exemple qui utilise ces annotations ? Une explication est une chose, mais un exemple concret en est une autre.

"OK. Je vais vous montrer un exemple. Je voulais juste ajouter que JAXB vous permet d'annoter des méthodes getter/setter au lieu de champs."

"Voici cet exemple que j'ai promis :"

Convertir un objet en XML
public static void main(String[] args) throws JAXBException
{
 // Create Cat and Zoo objects to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 Zoo zoo = new Zoo();
 zoo.animals.add(cat);
 zoo.animals.add(cat);

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class, Zoo.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // Here's the serialization itself
 marshaller.marshal(zoo, writer);

 // Convert everything written to the StringWriter into a String
 System.out.println(writer.toString());
}
Une classe dont les objets sont convertis en XML
@XmlType(name = "zoo")
@XmlRootElement
public class Zoo
{
 @XmlElementWrapper(name = "wild-animals", nillable = true)
 @XmlElement(name = "tiger")
 public List<Cat> animals = new ArrayList<>();
}

public class Cat
{
 @XmlElement(name = "catname")
 public String name;
 @XmlAttribute(name = "age")
 public int age;
 @XmlAttribute(name = "w")
 public int weight;

 public Cat()
 {
 }
}
Résultat de sérialisation et sortie d'écran :
<zoo> 
<wild-animals> 
<tiger age = "5" w = "4"> 
<catname>Missy</catname> 
</tiger> 
<tiger age = "5" w = "4"> 
<catname>Missy </catname> 
</tiger> 
</wild-animals> 
</zoo>

"Remarquez que cette fois, nous ne sérialisons pas un objet Cat, mais un objet Zoo qui stocke une collection d'objets Cat."

"L'objet chat a été ajouté deux fois à la collection, il se trouve donc deux fois dans le XML."

"La collection a sa propre étiquette ' animaux sauvages ' qui enveloppe tous les éléments de la collection."

"Les éléments d'âge et de poids sont devenus les attributs d'âge et de poids."

"En utilisant un attribut @XmlElement , nous avons changé la balise cat en une balise tigre ."

"Faites attention à la ligne 17. Ici, nous passons deux classes ( Zoo et Cat ) au contexte JAXB, puisqu'elles sont toutes les deux impliquées dans la sérialisation."

"Aujourd'hui était une journée très intéressante. Tellement de nouvelles informations."

"Oui. Je suis content pour toi. Maintenant, fais une courte pause et nous continuerons."