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

Как обрабатывать YAML с помощью Джексона

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

1. Введение

В этом коротком руководстве мы узнаем, как использовать Jackson для чтения и записи файлов YAML.

После того, как мы рассмотрим структуру нашего примера, мы будем использовать ObjectMapper для чтения файла YAML в объект Java, а также для записи объекта в файл.

2. Зависимости

Давайте добавим зависимость для формата данных Jackson YAML:

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

Мы всегда можем найти самую последнюю версию этой зависимости на Maven Central .

Наш объект Java использует LocalDate , поэтому давайте также добавим зависимость для типа данных JSR-310:

<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.0</version>
</dependency>

Опять же, мы можем посмотреть его самую последнюю версию на Maven Central .

3. Структура данных и объектов

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

Давайте сначала посмотрим на файл, который мы будем читать:

orderNo: A001
date: 2019-04-17
customerName: Customer, Joe
orderLines:
- item: No. 9 Sprockets
quantity: 12
unitPrice: 1.23
- item: Widget (10mm)
quantity: 4
unitPrice: 3.45

Затем давайте определим класс Order :

public class Order {
private String orderNo;
private LocalDate date;
private String customerName;
private List<OrderLine> orderLines;

// Constructors, Getters, Setters and toString
}

Наконец, давайте создадим наш класс OrderLine :

public class OrderLine {
private String item;
private int quantity;
private BigDecimal unitPrice;

// Constructors, Getters, Setters and toString
}

4. Чтение YAML

Мы собираемся использовать ObjectMapper Джексона для чтения нашего YAML-файла в объект Order , поэтому давайте настроим его сейчас:

mapper = new ObjectMapper(new YAMLFactory());

Нам нужно использовать метод findAndRegisterModules , чтобы Джексон правильно обработал нашу дату :

mapper.findAndRegisterModules();

Как только мы настроим наш ObjectMapper , мы просто используем readValue :

Order order = mapper.readValue(new File("src/main/resources/orderInput.yaml"), Order.class);

Мы обнаружим, что наш объект Order заполняется из файла, включая список OrderLine .

5. Написание YAML

Мы также собираемся использовать ObjectMapper для записи Order в файл. Но сначала давайте добавим к нему некоторую конфигурацию:

mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

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

По умолчанию наш файл будет начинаться с трех дефисов. Это совершенно верно для формата YAML, но мы можем отключить его, отключив функцию в YAMLFactory :

mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));

Убрав эту дополнительную настройку, давайте создадим Order :

List<OrderLine> lines = new ArrayList<>();
lines.add(new OrderLine("Copper Wire (200ft)", 1,
new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP)));
lines.add(new OrderLine("Washers (1/4\")", 24,
new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP)));
Order order = new Order(
"B-9910",
LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE),
"Customer, Jane",
lines);

Давайте напишем наш заказ, используя writeValue :

mapper.writeValue(new File("src/main/resources/orderOutput.yaml"), order);

Когда мы посмотрим на orderOutput.yaml , он должен выглядеть примерно так:

orderNo: "B-9910"
date: "2019-04-18"
customerName: "Customer, Jane"
orderLines:
- item: "Copper Wire (200ft)"
quantity: 1
unitPrice: 50.67
- item: "Washers (1/4\")"
quantity: 24
unitPrice: 0.15

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

В этом кратком руководстве мы узнали, как читать и записывать YAML в файлы и из них, используя библиотеку Джексона. Мы также рассмотрели несколько элементов конфигурации, которые помогут нам придать нашим данным желаемый вид.

Полный код примера закончился на GitHub .