Работа с сериализацией XML в Java и Kotlin

Возможно, вы сталкивались с ситуациями в своем приложении на основе Java/Kotlin, когда вам приходилось работать с XML. Вам нужно манипулировать XML и возвращать ответ на запрос или записывать в файл. У вас может быть старое приложение, которое все еще поддерживает некоторые устаревшие API, в которых вам нужно сериализовать строки XML. Существует множество способов работы с XML. В этой статье я поделюсь несколькими лучшими способами работы с XML.

Предварительное требование

  • Java LTS 17+
  • [Необязательно] Kotlin 1.6+, несколько примеров будут на Kotlin
  • [Необязательно] IntelliJ CE, вы можете использовать предпочтительную IDE

Настройка

Мои образцы кода также включают примеры Kotlin. Поэтому я создам Springboot, который также поддерживает Kotlin. Выбор фреймворка полностью зависит от вас. Данные образцы будут работать и без Springboot. Для этой демонстрации Вы можете сгенерировать стартовый проект по этой ссылке. Просто скачайте zip-файл xml-demo и извлеките его куда-нибудь. Обычно для извлечения требуется около 1–2 минут. После завершения загрузки Вы можете удалить или переименовать XmlDemoApplication.kt в XmlDemoApplication.java.

Давайте добавим наш первый код.

Объяснение.В приведенном выше коде я только что создал @RestController с @RequestMappping.

Вывод:попытаться получитьданные

curl http://localhost:8080/xml?name=Deepak
<name>Deepak</name>

Создайте файл Kotlin XmlDemoKt.kt. Добавьте приведенный ниже код в файл Kotlin.

Вывод:

curl http://localhost:8080/kt/xml?name=Deepak
<name>Deepak</name>

1. Использование текстового блока или шаблона строки

В Java 15 Java представила новую функцию Текстовый блок. Если вы используете Java 15 и выше, вы можете использовать TextBlock для записи многострочных строк. Это хорошее начало для написания XML-шаблона.

Самая большая проблема с TextBlock заключается в том, что он не поддерживает шаблоны в Text Block. Я имею в виду, что вы не можете использовать переменные и значения в TextBlock. Таким образом, вы должны использовать служебные методы, такие как formatted, чтобы присвоить значение переменной.
Это не относится к Котлину. Давайте посмотрим на код Kotlin.

Запрос:

## Java
curl -X POST http://localhost:8080/xml -H 'Content-Type: application/json' -d '{    "age": 20,    "name": "Stefanie Sampson",    "company": "INTERFIND",    "email": "[email protected]",    "address": {      "street": "Coleman Street, 683",      "city": "Spelter",      "state": "Marshall Islands",      "zip": 3748    }  }'
## Kotlin URL
http://localhost:8080/kt/xml

2. Использование шаблонизатора

Написание строк шаблона и манипулирование ими требует много времени и многословия. Вы можете избежать этого, используя механизм шаблонов, такой как Mustache или Thymeleaf. Принцип работы любого шаблонизатора одинаков. Вам нужно сначала разобрать шаблон и скомпилировать его. Позже вы сможете использовать скомпилированные объекты для генерации строковых значений.
Я покажу рабочий пример в движке Mustache. Настройка движка Mustache намного проще, чем Thymeleaf.

Шаблон усов. Создайте файл person-response.mustache в папке ресурсов. Чтение шаблона из папки ресурсов очень просто в Mustache.

Версия Котлина:

Версия Java:

Запрос:

## Kotlin 
curl -X POST http://localhost:8080/kt/template -H 'Content-Type: application/json' -d '{    "age": 20,    "name": "Stefanie Sampson",    "company": "INTERFIND",    "email": "[email protected]",    "address": {      "street": "Coleman Street, 683",      "city": "Spelter",      "state": "Marshall Islands",      "zip": 3748    }  }'
## Java URL
http://localhost:8080/template

Вы могли заметить, что теперь код очень похож на Java и Kotlin. Использование механизма шаблонов делает код более читабельным и простым. Однако одновременная поддержка шаблонов и POJO может быть утомительной и избыточной. В случае каких-либо изменений в данных или шаблоне мы должны одновременно изменить шаблон и POJO. Механизм шаблонов анализирует весь шаблон, что также снижает производительность приложения.

3. Использование сериализации Джексона

Вы также, возможно, заметили, что Springboot предоставляет сериализацию JSON из коробки. Springboot внутренне использует модуль Джексона FasterXml. Модуль Джексона — это очень удобный фреймворк для работы с типами данных JSON и XML. Мы можем легко настроить приложение Springboot для возврата XML-ответа. Для этого нам просто нужно добавить тег products в аннотацию @RequestMapping. Чтобы пометить POJO как ответ XML, нам также нужно пометить корневой класс аннотацией @JacksonXmlRootElement.

Примечание. Java не требует дополнительной настройки. Однако, если вы используете класс данных Kotlin. Вам необходимо зарегистрировать модуль Kotlin в картографе объектов.

Пример Java:

Пример Котлина:

Если вы не используете инфраструктуру Springboot, вы можете напрямую использовать преобразователь XML для преобразования POJO в строку XML.

// Java
person.name = "[Updated] %s".formatted(person.name);
return new XmlMapper().writeValueAsString(person);
// Kotlin
XmlMapper().writeValueAsString(p.copy(name = "[Updated] ${p.name}"))

Примечание. Вам следует создать один экземпляр XmlMapper, чтобы избежать утечки памяти.

Заключение

Вот несколько способов обработки строк XML. Если вы ищете более инновационный и декларативный способ написания XML. Вы можете посмотреть библиотеки Kotlin DSL, такие как kotlin-xml-builder.
Я особенно предпочитаю использование Jackson XML другим. Т.к. он очень удобен в использовании и прост в понимании.

Исходный код

Вы можете скачать все файлы с моей основной страницы Работа с XML-сериализацией и ответом в Java и Kotlin.