Sérialisation et désérialisation XML avec Jackson

Sérialisation XML et désérialisation avec Jackson

1. Vue d'ensemble

Dans ce didacticiel, nous allons examinerhow to serialize Java objects to XML data using Jackson 2.x and deserialize it back to a POJO.

Nous nous concentrerons sur le fonctionnement de base qui ne nécessite pas beaucoup de complexité ou de personnalisation.

2. ObjetXmlMapper

XmlMapper est la classe principale de Jackson 2.x qui nous aide dans la sérialisation, nous devrons donc en créer une instance:

XmlMapper mapper = new XmlMapper();

Cemapper  est disponible dans le jar dejackson-dataformat-xml, nous devons donc l'ajouter en tant que dépendance à nospom.xml:


    com.fasterxml.jackson.dataformat
    jackson-dataformat-xml
    2.9.8

3. Sérialiser Java en XML

XmlMapper est une sous-classe deObjectMapper qui est utilisée dans la sérialisation JSON. Cependant, il ajoute des réglages spécifiques à la classe parent.

Nous pouvons maintenant voir comment l'utiliser pour effectuer la sérialisation réelle. Créons d'abord une classe Java:

class SimpleBean {
    private int x = 1;
    private int y = 2;

    //standard setters and getters
}

3.1. Sérialiser vers le XMLString

Nous pouvons sérialiser notre objet Java dans le XMLString:

@Test
public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException {
    XmlMapper xmlMapper = new XmlMapper();
    String xml = xmlMapper.writeValueAsString(new SimpleBean());
    assertNotNull(xml);
}

En conséquence, nous obtiendrons:


    1
    2

3.2. Sérialiser dans le fichier XML

Nous pouvons également sérialiser notre objet Java dans le fichier XML:

@Test
public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.writeValue(new File("simple_bean.xml"), new SimpleBean());
    File file = new File("simple_bean.xml");
    assertNotNull(file);
}

Et ci-dessous, nous pouvons voir le contenu du fichier résultant nommésimple_bean.xml:


    1
    2

4. Désérialiser XML en Java

Dans cette section, nous verrons comment obtenir des objets Java à partir de XML.

4.1. Désérialiser à partir de la chaîne XML

Comme pour la sérialisation, nous pouvons également désérialiser une chaîne XML en un objet Java:

@Test
public void whenJavaGotFromXmlStr_thenCorrect() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    SimpleBean value
      = xmlMapper.readValue("12", SimpleBean.class);
    assertTrue(value.getX() == 1 && value.getY() == 2);
}

4.2. Désérialiser à partir du fichier XML

De même, si nous avons un fichier XML, nous pouvons le reconvertir en objet Java.

Ici, nous lisons d'abord le fichier dans un flux d'entrée, puis convertissons le flux d'entrée enString avec une méthode utilitaire simple.

Le reste du code est similaire à celui de la section 4.1:

@Test
public void whenJavaGotFromXmlFile_thenCorrect() throws IOException {
    File file = new File("simple_bean.xml");
    XmlMapper xmlMapper = new XmlMapper();
    String xml = inputStreamToString(new FileInputStream(file));
    SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class);
    assertTrue(value.getX() == 1 && value.getY() == 2);
}

La méthode d'utilité:

public String inputStreamToString(InputStream is) throws IOException {
    StringBuilder sb = new StringBuilder();
    String line;
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    while ((line = br.readLine()) != null) {
        sb.append(line);
    }
    br.close();
    return sb.toString();
}

5. Gestion des éléments capitalisés

Dans cette section, nous verrons comment gérer des scénarios dans lesquels nous avons soit du XML avec des éléments en majuscules à désérialiser, soit nous devons sérialiser des objets Java en XML avec un ou plusieurs éléments en majuscules.

5.1. Désérialiser à partir desString XML

Supposons que nous ayons un XML avec un champ en majuscule:


    1
    2

Afin de gérer correctement les éléments en majuscules, nous devons annoter le champ «x» avec l'annotation@JsonProperty:

class SimpleBeanForCapitalizedFields {
    @JsonProperty("X")
    private int x = 1;
    private int y = 2;

    // standard getters, setters
}

Nous pouvons maintenant désérialiser correctement un XMLString en un objet Java:

@Test
public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    SimpleBeanForCapitalizedFields value
      = xmlMapper.readValue(
      "12",
      SimpleBeanForCapitalizedFields.class);
    assertTrue(value.getX() == 1 && value.getY() == 2);
}

5.2. Sérialiser à la chaîne XML

En annotant les champs obligatoires avec@JsonProperty,, nous pouvons correctement sérialiser un objet Java en un XMLString avec un ou plusieurs éléments en majuscules:

@Test
public void whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect()
  throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"),
      new SimpleBeanForCapitalizedFields());
    File file = new File("target/simple_bean_capitalized.xml");
    assertNotNull(file);
}

6. Serialize List to XML

LeXmlMapper est capable de sérialiser un bean Java entier dans un document. Pour convertir un objet Java en XML, nous allons prendre un exemple simple avec l'objet imbriqué et les tableaux.

Notre intention est de sérialiser un objetPerson, ainsi que son objetAddress composé, en XML.

Notre XML final ressemblera à quelque chose comme:


    Rohan
    Daye
    
        9911034731
        9911033478
    
    
Name1 City1
Name2 City2

Notez que nos numéros de téléphone sont encapsulés dans un wrapperphoneNumbers alors que notre adresse ne l'est pas.

Nous pouvons exprimer cette nuance via l'annotation@JacksonXMLElementWrapper dans notre classePerson:

public final class Person {
    private String firstName;
    private String lastName;
    private List phoneNumbers = new ArrayList<>();
    @JacksonXmlElementWrapper(useWrapping = false)
    private List
address = new ArrayList<>(); //standard setters and getters }

En fait, nous pouvons changer le nom de l’élément d’habillage avec@JacksonXmlElementWrapper(localName = ‘phoneNumbers'). Ou, si nous ne voulons pas envelopper nos éléments, nous pouvons désactiver le mappage avec@JacksonXmlElementWrapper(useWrapping = false).

Et puis définissons notre stypeAddress :

public class Address {
    String streetName;
    String city;
    //standard setters and getters
}

Jackson takes care of the rest for us. Comme précédemment, nous pouvons simplement appeler à nouveauwriteValue:

private static final String XML = "...";

@Test
public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    Person person = testPerson(); // test data
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    xmlMapper.writeValue(byteArrayOutputStream, person);
    assertEquals(XML, byteArrayOutputStream.toString());
}

7. Désérialiser XML enList

Jackson peut aussi lire du XML contenant des listes d'objets.

Si nous prenons notre même XML qu'avant, la méthodereadValue fonctionne très bien:

@Test
public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    Person value = xmlMapper.readValue(XML, Person.class);
    assertEquals("City1", value.getAddress().get(0).getCity());
    assertEquals("City2", value.getAddress().get(1).getCity());
}

8. Conclusion

Cet article simple explique comment sérialiser un simple POJO en XML et obtenir un POJO à partir de données XML de base.

Nous avons également étudié la possibilité de sérialiser et de désérialiser les beans complexes contenant des collections.

Le code source qui accompagne cet article est disponible surGitHub.