1. 概述
本教程將學習如何使用 Jackson 2.x 將 Java 對象序列化為 XML 數據,並將它們反序列化回 POJO。
我們將重點關注基本操作,無需過多複雜性或自定義配置。
2. XmlMapper 對象
XmlMapper 是 Jackson 2.x 中的主要類,它能幫助我們進行序列化。因此,我們需要創建一個它的實例:
XmlMapper mapper = new XmlMapper();這個mapper在 jackson-dataformat-xml jar 中可用,因此我們需要將其作為依賴項添加到我們的 pom.xml 中:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.1</version>
</dependency>請檢查 Maven 倉庫中 jackson-dataformat-xml 依賴的最新版本。
3. 將 Java 序列化為 XML
XmlMapper 是 ObjectMapper 的子類,後者用於 JSON 序列化;但是,它在父類上添加了一些 XML 特定的調整。下面我們來看如何使用它進行實際的序列化。首先,我們創建一個 Java 類:
class SimpleBean {
private int x = 1;
private int y = 2;
//standard setters and getters
}3.1. 將 Java 對象序列化為 XML 字符串
我們可以將我們的 Java 對象序列化為 XML 字符串:
@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. 將對象序列化到 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 的內容:
<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 文件反序列化
同樣,如果存在一個 XML 文件,我們可以將其轉換回 Java 對象。
@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>為了正確處理大寫元素,我們需要使用 @JsonProperty 註解標記“x”字段:
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(
"<SimpleBeanForCapitalizedFields><X>1</X><y>2</y></SimpleBeanForCapitalizedFields>",
SimpleBeanForCapitalizedFields.class);
assertTrue(value.getX() == 1 && value.getY() == 2);
}5.2. 將對象序列化為 XML 字符串
通過使用 @JsonProperty 註解標記所需的字段,我們可以將 Java 對象正確地序列化為包含一個或多個大寫元素的 XML String。
@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 反序列化為 列表
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。