Вопрос или проблема
У меня есть файл 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.
Возможные решения
-
Использование аннотаций: Вы можете использовать аннотации, такие как
@YamlProperty
(в зависимости от используемой библиотеки), чтобы указать, какое поле YAML соответствует какому свойству в Java. Однако, обратите внимание, что SnakeYAML в своей стандартной реализации не поддерживает такой функционал напрямую. -
Создание кастомного конвертера: Вам необходимо создать свой собственный конвертер, который будет обрабатывать поля с дефисами. Например, вы можете переопределить метод
construct
и добавить в него логику преобразования ключей. -
Преобразование ключей вручную: Один из самых простых способов – это заранее преобразовать ваш YAML-файл, заменив дефисы на подчеркивания. Это можно сделать с помощью текстового редактора или скрипта перед загрузкой файла:
resource_path: "src/resource"
С использованием этого изменения ваша текущая реализация должна заработать без дополнительных модификаций.
-
Использование модуля 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 могут иметь различия, требующие дополнительных шагов для оптимизации. Используя одно из предложенных решений, вы сможете избежать ошибок и эффективно работать с вашими данными.