1. 概述
在本教程中,我們將學習如何使用 Jackson 將 XML 消息轉換為 JSON。
對於初次接觸 Jackson 的讀者,建議先熟悉一下基本概念。
2. Jackson 簡介
我們可以用三種不同的方式來解析 JSON,藉助 Jackson:
- 第一種,也是最常見的一種,是使用數據綁定,即 ObjectMapper。
- 第二種是將其映射到樹形數據結構,即使用 TreeTraversingParser 和 JsonNode。
- 第三種是按樹形數據結構的節點進行流式處理,即使用 JsonParser 和 JsonGenerator。
現在,Jackson 還支持前兩種方法用於 XML 數據。因此,讓我們看看 Jackson 如何幫助我們進行一種格式到另一種格式的轉換。
3. 依賴項
首先,我們需要將 jackson-databind 依賴項添加到我們的 pom.xml 中:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>這個庫將允許我們使用數據綁定 API。
第二種是 jackson-dataformat-xml,它添加了 Jackson 的 XML 支持:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.17.2</version>
</dependency>4. 數據綁定
數據綁定,簡單來説,是指我們想要將序列化數據直接映射到 Java 對象。
為了探索這一點,讓我們使用 花和 顏色屬性定義我們的 XML:
<Flower>
<name>Poppy</name>
<color>RED</color>
<petals>9</petals>
</Flower>
這與這種 Java 語法類似:
public class Flower {
private String name;
private Color color;
private Integer petals;
// getters and setters
}
public enum Color { PINK, BLUE, YELLOW, RED; }我們第一步是解析XML為Flower實例。為此,讓我們創建一個XmlMapper實例,這是Jackson的XML等效對象,用於ObjectMapper的readValue方法。
XmlMapper xmlMapper = new XmlMapper();
Flower poppy = xmlMapper.readValue(xml, Flower.class);一旦我們獲取了 Flower 實例, 我們將使用熟悉的 ObjectMapper 將其輸出為 JSON:
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(poppy);並且,作為結果,我們得到我們的 JSON 對應值:
{
"name":"Poppy",
"color":"RED",
"petals":9
}5. 樹遍歷
在某些情況下,直接觀察樹結構可以提供更大的靈活性,例如當我們不想維護中間類或僅想轉換結構的一部分時。
儘管如此,正如我們稍後將看到的,它也伴隨着一些權衡。
第一步與我們使用數據綁定時的一致,但這次我們將使用 readTree 方法:
XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xml.getBytes());已經完成這個操作後,我們將會得到一個 JsonNode 對象,它有 3 個子節點,正如我們所期望的:name, color, 和petals。
然後,我們可以再次使用 ObjectMapper,只需將我們的 JsonNode 發送過去即可。
ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);現在,結果與我們上次的例子略有不同:
{
"name":"Poppy",
"color":"RED",
"petals":"9"
}仔細檢查後,我們發現花瓣屬性被序列化為字符串,而不是數字! 這是因為 readTree 在沒有顯式定義的情況下不會推斷數據類型。
5.1. 侷限性
並且,Jackson 的 XML 樹遍歷支持存在一些侷限性:
- Jackson 無法區分對象和數組。由於 XML 缺乏原生結構來區分對象和對象列表,Jackson 會將重複的元素簡單地合併為一個值。
- 並且,由於 Jackson 想要將每個 XML 元素映射到 JSON 節點,因此它不支持混合內容。
由於這些原因,官方 Jackson 文檔建議不要使用 Tree 模型來解析 XML。
6. 內存限制
然而,這兩個方案的顯著缺點是,整個XML文檔必須一次性加載到內存中才能進行轉換。 除非Jackson支持將樹結構作為令牌進行流式處理,否則我們將被這種限制所束縛,或者可以考慮使用像XMLStreamReader 這樣的自定義解決方案。
7. 結論
在本教程中,我們簡要學習了 Jackson 如何讀取 XML 數據以及將其寫入 JSON 的不同方法。我們還快速瞭解了每種支持的方法的侷限性。