XML сериализация и десериализация с Джаксън

1. Общ преглед

В този урок ще разгледаме как да сериализираме Java обектите към XML данни с помощта на Jackson 2.x и да ги десериализираме обратно към POJO .

Ще се съсредоточим върху основната операция, която не изисква много сложност или персонализация.

2. XmlMapper обект

XmlMapper е основният клас от Jackson 2.x, който ни помага при сериализацията, така че ще трябва да създадем негов екземпляр:

XmlMapper mapper = new XmlMapper();

Това картографиране е налично в jackson-dataformat-xml буркан, така че трябва да го добавим като зависимост към нашия pom.xml :

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

Моля, проверете най-новата версия на зависимостта jackson-dataformat-xml в хранилището на Maven.

3. Сериализирайте Java в XML

XmlMapper е подклас на ObjectMapper, който се използва при JSON сериализация. Той обаче добавя някои XML специфични ощипвания към родителския клас.

Сега можем да разгледаме как да го използваме, за да направим действителната сериализация. Нека първо създадем клас Java:

class SimpleBean { private int x = 1; private int y = 2; //standard setters and getters }

3.1. Сериализирайте в XML String

Можем да сериализираме нашия Java обект в XML String :

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

В резултат ще получим:

 1 2 

3.2. Сериализирайте в XML файла

Също така можем да сериализираме нашия Java обект към 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); }

И по-долу можем да видим съдържанието на получения файл с име simple_bean.xml :

 1 2 

4. Десериализирайте XML към Java

В този раздел ще разгледаме как да получим Java обекти от XML.

4.1. Десериализирайте от XML низ

Както при сериализацията, ние също можем да десериализираме XML String обратно към 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. Десериализирайте от XML файла

По същия начин, ако имаме XML файл, можем да го конвертираме обратно в Java обект.

Тук първо четем файла във входен поток и след това конвертираме входния поток в String с прост полезен метод.

Останалата част от кода е подобна на тази от раздел 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); }

Полезният метод:

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. Работа с главни букви

В този раздел ще разгледаме как да се справим със сценарии, при които имаме XML с главни букви за десериализиране или трябва да сериализираме Java обектите в XML с един или повече елементи с главни букви.

5.1. Десериализирайте от XML низ

Да приемем, че имаме XML с едно поле с главни букви:

 1 2 

За да се справим правилно с главни букви елементи, трябва да коментираме полето „x“ с анотацията @JsonProperty :

class SimpleBeanForCapitalizedFields { @JsonProperty("X") private int x = 1; private int y = 2; // standard getters, setters }

Вече можем правилно да десериализираме XML String обратно към 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. Сериализирайте в XML String

Чрез анотиране на задължителни полета с @JsonProperty, можем правилно да сериализираме Java обект в XML низ с един или повече главни елементи:

@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. Сериализирайте списъка в XML

В XmlMapper е в състояние да издавам цяла Java боб в документ. За да конвертираме Java обект в XML, ще вземем прост пример с вложения обект и масиви.

Our intent is to serialize a Person object, along with its composed Address object, into XML.

Our final XML will look something like:

 Rohan Daye  9911034731 9911033478   Name1 City1   Name2 City2  

Notice that our phone numbers are encapsulated in a phoneNumbers wrapper while our address is not.

We can express this nuance via the @JacksonXMLElementWrapper annotation in our Person class:

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 }

Actually, we can change the wrapping element name with @JacksonXmlElementWrapper(localName = ‘phoneNumbers'). Or, if we don't want to wrap our elements, we can disable the mapping with @JacksonXmlElementWrapper(useWrapping = false).

And then let's define our Address type:

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

Джаксън се грижи за останалото вместо нас. Както и преди, можем просто да извикаме writeValue отново:

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. Десериализирайте XML в списък

Джаксън също може да чете XML, който съдържа списъци с обекти.

Ако вземем същия XML като преди, методът readValue се справя добре:

@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. Заключение

Тази проста статия илюстрира как да сериализирате прост POJO към XML и да получите POJO от основни XML данни.

Също така разгледахме как да сериализираме и десериализираме сложни зърна, които съдържат колекции.

Изходният код, придружаващ тази статия, е достъпен на GitHub.