Contents

Jackson 将XML转换为JSON

1. 概述

在本教程中,我们将了解如何使用 Jackson 将 XML 消息转换为 JSON。

2. Jackson简介

我们可以考虑使用 Jackson 以三种不同的方式解析 JSON:

现在,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 对象。

为了探索这一点,让我们FlowerColor属性定义我们的 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,正如我们所料:namecolorpetals

然后,我们可以再次使用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 的东西来滚动我们自己的。