XML-serialisering en deserialisering met Jackson

1. Overzicht

In deze tutorial gaan we kijken naar hoe u Java-objecten kunt serialiseren naar XML-gegevens met Jackson 2.x en deze terug kunt deserialiseren naar een POJO.

We zullen ons concentreren op de basisbewerking die niet veel complexiteit of maatwerk vereist.

2. XmlMapper Voorwerp

XmlMapper is de hoofdklasse van Jackson 2.x die ons helpt bij het serialiseren, dus we zullen er een instantie van moeten maken:

XmlMapper-mapper = nieuwe XmlMapper ();

Dit mapper is beschikbaar in jackson-dataformat-xml jar, dus we moeten het als een afhankelijkheid toevoegen aan onze pom.xml:

 com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.11.1 

Controleer de laatste versie van de jackson-dataformat-xml-afhankelijkheid in de Maven-repository.

3. Serialiseer Java naar XML

XmlMapper is een subklasse van ObjectMapper die wordt gebruikt bij JSON-serialisering. Het voegt echter enkele XML-specifieke tweaks toe aan de bovenliggende klasse.

We kunnen nu kijken hoe we het kunnen gebruiken om de daadwerkelijke serialisering uit te voeren. Laten we eerst een Java-klasse maken:

class SimpleBean {private int x = 1; privé int y = 2; // standaard setters en getters}

3.1. Serialiseer naar de XML Draad

We kunnen ons Java-object serialiseren in de XML Draad:

@Test openbare leegte whenJavaSerializedToXmlStr_thenCorrect () gooit JsonProcessingException {XmlMapper xmlMapper = nieuwe XmlMapper (); String xml = xmlMapper.writeValueAsString (nieuwe SimpleBean ()); assertNotNull (xml); }

Als resultaat krijgen we:

 1 2 

3.2. Serialiseer naar het XML-bestand

We kunnen ons Java-object ook serialiseren naar het XML-bestand:

@Test openbare leegte whenJavaSerializedToXmlFile_thenCorrect () gooit IOException {XmlMapper xmlMapper = nieuwe XmlMapper (); xmlMapper.writeValue (nieuw bestand ("simple_bean.xml"), nieuwe SimpleBean ()); Bestandsbestand = nieuw bestand ("simple_bean.xml"); assertNotNull (bestand); }

En hieronder kunnen we de inhoud van het resulterende bestand met de naam zien simple_bean.xml:

 1 2 

4. Deserialiseer XML naar Java

In deze sectie zullen we bekijken hoe u Java-objecten uit XML kunt halen.

4.1. Deserialiseren vanuit de XML-string

Net als bij serialisatie kunnen we een XML-string ook deserialiseren naar een Java-object:

@Test openbare leegte whenJavaGotFromXmlStr_thenCorrect () gooit IOException {XmlMapper xmlMapper = nieuwe XmlMapper (); SimpleBean-waarde = xmlMapper.readValue ("12", SimpleBean.class); assertTrue (value.getX () == 1 && value.getY () == 2); }

4.2. Deserialiseren vanuit het XML-bestand

Evenzo, als we een XML-bestand hebben, kunnen we het terug converteren naar een Java-object.

Hier lezen we het bestand eerst in een invoerstroom en vervolgens converteren we de invoerstroom naar een Draad met een eenvoudige gebruiksmethode.

De rest van de code is vergelijkbaar met die uit sectie 4.1:

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

De hulpprogramma-methode:

openbare String inputStreamToString (InputStream is) gooit IOException {StringBuilder sb = nieuwe StringBuilder (); String lijn; BufferedReader br = nieuwe BufferedReader (nieuwe InputStreamReader (is)); while ((line = br.readLine ())! = null) {sb.append (regel); } br.close (); retourneer sb.toString (); }

5. Omgaan met hoofdletters

In deze sectie zullen we bekijken hoe we scenario's kunnen afhandelen waarin we XML met hoofdletters hebben om te deserialiseren of we Java-objecten moeten serialiseren naar XML met een of meer elementen met hoofdletters.

5.1. Deserialiseren vanuit de XML Draad

Laten we zeggen dat we een XML hebben met één veld in hoofdletters:

 1 2 

Om elementen met hoofdletters correct te kunnen verwerken, moeten we het "x" -veld annoteren met de @JsonProperty annotatie:

klasse SimpleBeanForCapitalizedFields {@JsonProperty ("X") privé int x = 1; privé int y = 2; // standaard getters, setters}

We kunnen nu een XML correct deserialiseren Draad terug naar een Java-object:

@Test openbare leegte whenJavaGotFromXmlStrWithCapitalElem_thenCorrect () gooit IOException {XmlMapper xmlMapper = nieuwe XmlMapper (); SimpleBeanForCapitalizedFields waarde = xmlMapper.readValue ("12", SimpleBeanForCapitalizedFields.class); assertTrue (value.getX () == 1 && value.getY () == 2); }

5.2. Serialiseer naar de XML-string

Door verplichte velden te annoteren met @JsonProperty, we kunnen een Java-object correct serialiseren in een XML Draad met een of meer hoofdletters:

@Test openbare leegte whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect () gooit IOException {XmlMapper xmlMapper = nieuwe XmlMapper (); xmlMapper.writeValue (nieuw bestand ("target / simple_bean_capitalized.xml"), nieuwe SimpleBeanForCapitalizedFields ()); File file = new File ("target / simple_bean_capitalized.xml"); assertNotNull (bestand); }

6. Serialiseren Lijst naar XML

De XmlMapper kan een volledige Java-bean in een document serialiseren. Om een ​​Java-object naar XML te converteren, nemen we een eenvoudig voorbeeld met het geneste object en de arrays.

Het is onze bedoeling om een Persoon object, samen met zijn samengesteld Adres object, naar XML.

Onze uiteindelijke XML ziet er ongeveer zo uit:

 Rohan Daye 9911034731 9911033478 Naam1 Plaats1 Naam2 Plaats2 

Merk op dat onze telefoonnummers zijn ingekapseld in een telefoonnummers wrapper terwijl ons adres dat niet is.

We kunnen deze nuance uitdrukken via de @JacksonXMLElementWrapper annotatie in onze Persoon klasse:

openbare laatste klas Persoon {privé String firstName; private String achternaam; private List phoneNumbers = nieuwe ArrayList (); @JacksonXmlElementWrapper (useWrapping = false) privélijstadres = nieuwe ArrayList (); // standaard setters en getters}

Eigenlijk kunnen we de naam van het wrapping-element wijzigen met @JacksonXmlElementWrapper (localName = ‘phoneNumbers '). Of, als we onze elementen niet willen omwikkelen, kunnen we de mapping uitschakelen met @JacksonXmlElementWrapper (useWrapping = false).

En laten we dan onze definiëren Adres type:

openbare klasse Adres {String streetName; String stad; // standaard setters en getters}

Jackson zorgt voor de rest. Net als voorheen kunnen we gewoon bellen writeValue opnieuw:

private static final String XML = "..."; @Test openbare leegte whenJavaSerializedToXmlFile_thenSuccess () gooit IOException {XmlMapper xmlMapper = nieuwe XmlMapper (); Persoon persoon = testPerson (); // testgegevens ByteArrayOutputStream byteArrayOutputStream = nieuwe ByteArrayOutputStream (); xmlMapper.writeValue (byteArrayOutputStream, persoon); assertEquals (XML, byteArrayOutputStream.toString ()); }

7. Deserialiseer XML naar Lijst

Jackson kan ook XML lezen die lijsten met objecten bevat.

Als we onze zelfde XML nemen als voorheen, de readValue methode doet het prima:

@Test openbare leegte whenJavaDeserializedFromXmlFile_thenCorrect () gooit IOException {XmlMapper xmlMapper = nieuwe XmlMapper (); Persoonswaarde = xmlMapper.readValue (XML, Person.class); assertEquals ("City1", value.getAddress (). get (0) .getCity ()); assertEquals ("City2", value.getAddress (). get (1) .getCity ()); }

8. Conclusie

Dit eenvoudige artikel illustreert hoe u een eenvoudige POJO naar XML kunt serialiseren en een POJO kunt verkrijgen op basis van XML-basisgegevens.

We hebben ook onderzocht hoe complexe bonen met verzamelingen kunnen worden geserialiseerd en gedeserialiseerd.

De broncode die bij dit artikel hoort, is beschikbaar op GitHub.