Jackson XML序列化與反序列化

Data,Jackson,XML
Remote
1
10:58 PM · Nov 30 ,2025

1. 概述

在本教程中,我們將學習如何使用 Jackson 2.x 將 Java 對象序列化為 XML 數據,並將它們反序列化回 POJO。

我們將專注於基本操作,不需要太多複雜性或自定義。

2. XmlMapper 對象

XmlMapper 是 Jackson 2.x 中的主要類,它可以幫助我們進行序列化,因此我們需要創建一個它的實例:

XmlMapper mapper = new XmlMapper();

這個 mapperjackson-dataformat-xml jar 中可用,因此我們需要將其添加到我們的 pom.xml 中:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.11.1</version>
</dependency>

請查看 最新版本的 jackson-dataformat-xml 依賴項 在 Maven 倉庫中。

3. Serialize Java to XML

XmlMapper

ObjectMapper

的一個子類,該類用於 JSON 序列化;但是,它添加了一些 XML 特定的調整以修改父類。

讓我們看看如何使用它來進行實際的序列化。首先,讓我們創建一個 Java 類:

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

3.1. Serialize to the XML String

我們可以將 Java 對象序列化為 XML String

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

結果如下:

<SimpleBean>
    <x>1</x>
    <y>2</y>
</SimpleBean>

3.2. Serialize to the XML File

我們還可以將 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的內容:

<SimpleBean>
    <x>1</x>
    <y>2</y>
</SimpleBean>

4. 反序列化 XML 到 Java在本節中,我們將探討如何從 XML 中獲取 Java 對象。

4.1. 從 XML 字符串反序列化

與序列化類似,我們也可以將 XML 字符串反序列化回 Java 對象:

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

4.2. 從 XML 文件反序列化

同樣,如果 chúng ta có một tệp XML, chúng ta có thể chuyển đổi nó thành một Java đối tượng.

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

5. 處理大寫元素

在本節中,我們將討論如何處理我們既有帶有大寫元素 XML 進行反序列化,又需要將 Java 對象序列化為 XML,其中一個或多個元素是大寫的場景。

5.1. 從 XML 字符串反序列化

假設我們有一個帶有大寫字段的 XML:

<SimpleBeanForCapitalizedFields>
    <X>1</X>
    <y>2</y>
</SimpleBeanForCapitalizedFields>

為了正確處理大寫元素,我們需要使用 標註 “x” 字段:

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

    // 標準的 getter, setter
}

現在我們可以正確地將 XML 字符串反序列化為 Java 對象:

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

5.2. 將 Java 對象序列化為 XML 字符串

通過使用 標註所需的字段,我們可以正確地將 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 Bean 序列化為文檔。要將 Java 對象轉換為 XML,我們將使用一個包含嵌套對象和數組的簡單示例。

我們的目標是將 Person對象及其組成的對象 Address對象序列化為 XML。

我們的最終 XML 將大致如下:

<Person>
    <firstName>Rohan</firstName>
    <lastName>Daye</lastName>
    <phoneNumbers>
        <phoneNumbers>9911034731</phoneNumbers>
        <phoneNumbers>9911033478</phoneNumbers>
    </phoneNumbers>
    <address>
        <streetName>Name1</streetName>
        <city>City1</city>
    </address>
    <address>
        <streetName>Name2</streetName>
        <city>City2</city>
    </address>
</Person>

請注意,我們的電話號碼被封裝在 phoneNumbers 包裝器中,而我們的地址則沒有。

我們可以通過在 Person 類中添加 @JacksonXMLElementWrapper 註解來表達這種細微差別:

public final class Person {
    private String firstName;
    private String lastName;
    private List<String> phoneNumbers = new ArrayList<>();
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Address> address = new ArrayList<>();

    //standard setters and getters
}

事實上,我們可以使用 @JacksonXmlElementWrapper(localName = ‘phoneNumbers’). 更改包裝元素名稱,或者,如果我們不想為我們的元素進行包裝,我們可以使用 @JacksonXmlElementWrapper(useWrapping = false) 禁用映射。

然後我們將定義我們的 Address 類型:

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

Jackson 會代表我們處理好一切。 就像之前一樣,我們可以簡單地再次調用 writeValue

private static final String XML = "<Person>...</Person>";

@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 反序列化為 List

Jackson 可以讀取包含對象列表的 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,以及如何從基本的XML數據中獲取POJO。

我們還探討了如何序列化和反序列化包含集合的複雜Bean。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.