Jackson 将XML转换为JSON
1. 概述
在本教程中,我们将了解如何使用 Jackson 将 XML 消息转换为 JSON。
2. Jackson简介
我们可以考虑使用 Jackson 以三种不同的方式解析 JSON:
- 第一个也是最常见的是与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.13.0</version>
</dependency>
这个库将允许我们使用数据绑定 API。
第二个是jackson-dataformat-xml ,它添加了 Jackson 的 XML 支持:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.0</version>
</dependency>
4. 数据绑定
数据绑定,简单来说,就是我们想要将序列化的数据直接映射到 Java 对象。
为了探索这一点,让我们用Flower和Color属性定义我们的 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 的ObjectMapper等效 XML并使用它的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());
完成此操作后,我们将拥有一个具有 3 个子节点的JsonNode,正如我们所料: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 官方文档 建议不要使用树模型来解析 XML。
6. 内存限制
现在,这两种方法都有一个明显的缺点,即整个 XML 需要一次在内存中才能执行转换。 在 Jackson 支持将树结构作为标记流式传输之前,我们将受制于这个约束,或者我们需要看看使用类似 XMLStreamReader 的东西来滚动我们自己的。