Перейти к основному содержимому

Преобразование XML в JSON с помощью Джексона

· 4 мин. чтения

1. Обзор

В этом руководстве мы увидим, как преобразовать XML-сообщение в JSON с помощью Jackson.

Читателям, плохо знакомым с Джексоном, рекомендуется сначала ознакомиться с основами .

2. Знакомство с Джексоном

С Джексоном мы можем думать о парсинге JSON тремя разными способами:

  • Первый и самый распространенный — привязка данных с помощью ObjectMapper.
  • Второй — сопоставление с древовидной структурой данных с помощью TreeTraversingParser и JsonNode.
  • И третий — стримить древовидную структуру данных по токену, используя JsonParser и JsonGenerator.

Теперь Джексон также поддерживает первые два для данных XML. Таким образом, давайте посмотрим, как Джексон может помочь нам преобразовать один формат в другой.

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 , который добавляет поддержку XML Джексона:

<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.0</version>
</dependency>

4. Привязка данных

Проще говоря, привязка данных — это когда мы хотим отобразить сериализованные данные непосредственно в объект Java.

Чтобы изучить это, давайте определим наш XML со свойствами Flower и Color :

<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 , XML-эквивалент Джексона для ObjectMapper , и воспользуемся его методом readValue :

XmlMapper xmlMapper = new XmlMapper();
Flower poppy = xmlMapper.readValue(xml, Flower.class);

Как только у нас будет наш экземпляр Flower , мы захотим записать его как JSON, используя знакомый ObjectMapper :

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 дочерних элемента: имя, цвет и лепестки .

Затем мы снова можем использовать ObjectMapper , просто отправив вместо этого наш JsonNode :

ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);

Теперь результат немного отличается от нашего последнего примера:

{
"name":"Poppy",
"color":"RED",
"petals":"9"
}

При внимательном рассмотрении мы видим, что атрибут лепестков сериализуется в строку, а не в число! Это связано с тем, что readTree не выводит тип данных без явного определения.

5.1. Ограничения

Кроме того, существуют определенные ограничения поддержки обхода XML-дерева Джексона:

  • Джексон не может отличить объект от массива. Поскольку в XML отсутствуют собственные структуры, позволяющие отличить объект от списка объектов, Джексон просто сопоставит повторяющиеся элементы в одно значение.
  • А поскольку Джексон хочет сопоставить каждый элемент XML с узлом JSON, он не поддерживает смешанный контент.

По этим причинам официальная документация Джексона не рекомендует использовать древовидные модели для разбора XML .

6. Ограничения памяти

Теперь у обоих есть заметный недостаток, заключающийся в том, что весь XML должен быть в памяти сразу, чтобы выполнить преобразование. Пока Джексон не поддерживает потоковую передачу древовидной структуры в виде токенов, мы застрянем на этом ограничении или нам нужно будет взглянуть на создание собственной структуры с помощью чего-то вроде XMLStreamReader .

7. Заключение

В этом руководстве мы кратко изучили различные способы, которыми Джексон может читать XML-данные и записывать их в JSON. Кроме того, мы кратко рассмотрели ограничения каждого поддерживаемого подхода.

Как обычно, полный исходный код, сопровождающий руководство, доступен на GitHub .