Парсинг полей YAML с дефисами с помощью SnakeYAML?

Вопрос или проблема

У меня есть файл yaml, который выглядит так:

resource-path: "src/resource"

Класс данных генерируется с помощью lombok и имеет методы getResourcePath и setResourcePath. Я проверил это, распечатав методы в классе, чтобы убедиться.

Когда я пытаюсь заполнить этот класс данных, я получаю эту ошибку:

Не удается найти свойство resource-path в классе.

А код, который я использую для парсинга yaml и заполнения класса данных, выглядит просто так:

Yaml yaml = new Yaml();
yaml.loadAs(new FileInputStream(dataFile), Data.class);

Я понимаю, что snakeyaml будет выводить имя поля в camelcase из имени поля с дефисами. Так что в моем случае это должно быть getResourcePath и setResourcePath, которые оба находятся в классе данных. Я читал документацию, но не вижу ничего, что могло бы быть полезным. Есть ли какое-то параметр или что-то другое, что я упускаю?

Я использую snakeyaml 2.18.

Ответ или решение

Для успешного парсинга YAML-файлов с использованием SnakeYAML и правильного сопоставления названий полей, необходимо учитывать особенности работы с именами полей, особенно когда они содержат дефисы. В вашем случае ключ resource-path в YAML не может быть напрямую сопоставлен с методом getResourcePath класса, сгенерированного Lombok, из-за наличия дефиса.

Почему возникает ошибка?

Ошибка, которую вы получаете:

Unable to find property resource-path on class.

указывает на то, что SnakeYAML не может найти соответствующее свойство для ключа resource-path. Дело в том, что по умолчанию SnakeYAML не преобразует ключи с дефисами в формат CamelCase.

Возможные решения

  1. Использование аннотаций: Вы можете использовать аннотации, такие как @YamlProperty (в зависимости от используемой библиотеки), чтобы указать, какое поле YAML соответствует какому свойству в Java. Однако, обратите внимание, что SnakeYAML в своей стандартной реализации не поддерживает такой функционал напрямую.

  2. Создание кастомного конвертера: Вам необходимо создать свой собственный конвертер, который будет обрабатывать поля с дефисами. Например, вы можете переопределить метод construct и добавить в него логику преобразования ключей.

  3. Преобразование ключей вручную: Один из самых простых способов – это заранее преобразовать ваш YAML-файл, заменив дефисы на подчеркивания. Это можно сделать с помощью текстового редактора или скрипта перед загрузкой файла:

    resource_path: "src/resource"

    С использованием этого изменения ваша текущая реализация должна заработать без дополнительных модификаций.

  4. Использование модуля Jackson: Если вы рассматриваете возможность использования других библиотек, Jackson YAML поддерживает работу с полями и их маппинг очень гибко. Он позволяет использовать конфигурацию для маппинга полей, в том числе для тех, которые содержат дефисы.

Пример с кастомным конвертером

Вот пример, как можно реализовать кастомный конвертер, который будет преобразовывать ваше YAML поле с дефисом в корректное для Java свойство:

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

class Data {
    private String resourcePath;

    // Геттер и сеттер
    public String getResourcePath() {
        return resourcePath;
    }

    public void setResourcePath(String resourcePath) {
        this.resourcePath = resourcePath;
    }
}

public class CustomYamlConstructor extends Constructor {
    public CustomYamlConstructor() {
        super(Data.class);
    }

    @Override
    protected Object constructJavaBean2ndStep(Object bean, NodeTuple nodeTuple) {
        String propertyName = nodeTuple.getKeyNode().getValue();
        if ("resource-path".equals(propertyName)) {
            propertyName = "resourcePath"; // Изменяем ключ на корректный
        }
        return super.constructJavaBean2ndStep(bean, new NodeTuple(new ScalarNode(...), new ScalarNode(...)));
    }
}

// Использование
Yaml yaml = new Yaml(new CustomYamlConstructor());
Data data = yaml.loadAs(new FileInputStream(dataFile), Data.class);

Заключение

При работе с hyphenated полями в YAML с использованием SnakeYAML, важно помнить, что синтаксис YAML и структуры данных в Java могут иметь различия, требующие дополнительных шагов для оптимизации. Используя одно из предложенных решений, вы сможете избежать ошибок и эффективно работать с вашими данными.

Оцените материал
Добавить комментарий

Капча загружается...