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>
請查看 最新版本的 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。