Автор оригинала: Taimoor Choudhary.
Вступление
YAML расшифровывается как YAML-это не язык разметки, это язык сериализации данных, наиболее часто используемый для указания деталей конфигурации проекта. Основная мотивация YAML заключается в том, что он разработан в удобном для человека формате. С первого взгляда мы можем получить представление о свойствах и их соответствующих значениях, а также о взаимосвязи между свойствами, если она существует.
Поскольку файлы YAML в настоящее время часто используются, почти в каждом другом проекте мы сталкиваемся со сценарием, когда нам приходится управлять данными в файлах YAML с помощью нашего кода. Существует множество библиотек с открытым исходным кодом, доступных для обработки файлов YAML на Java.
Для достижения этой цели мы можем использовать любую из двух популярных библиотек: Jackson или SnakeYaml .
В этой статье мы сосредоточимся на Как читать и записывать файлы YAML на Java с помощью SnakeYaml .
Змеиный ям
SnakeYaml – это библиотека синтаксического анализа YAML с высокоуровневым API для сериализации и десериализации документов YAML.
Точкой входа для SnakeYaml является класс Yaml , аналогично тому, как класс ObjectMapper является точкой входа в Джексон .
Загрузка документов может быть выполнена для отдельных документов с помощью метода load() или в пакетном режиме с помощью метода loadAll () . Методы принимают Входной поток , который является обычным форматом для поиска файлов, а также Строковые объекты, содержащие допустимые данные YAML.
С другой стороны, мы можем сбрасывать() объекты Java в документы YAML с легкостью – где ключи/поля и значения отображаются в документе.
Естественно, SnakeYaml хорошо работает с Java Maps , учитывая структуру <ключ>:<значение> , однако вы также можете работать с пользовательскими объектами Java.
Если вы используете Maven, установите SnakeYaml, добавив следующую зависимость:
org.yaml snakeyaml ${org.snakeyaml.version}
И если вы используете Gradle , установка SnakeYaml так же проста, как включение следующего в ваш файл Gradle:
compile group: 'org.yaml', name: 'snakeyaml', version: '{version}'
Вы можете ознакомиться с последней версией библиотеки в Центральном репозитории Maven .
Чтение YAML с помощью SnakeYaml
SnakeYaml позволяет считывать файл YAML в простой объект Map или анализировать файл и преобразовывать его в пользовательский объект Java. В зависимости от ваших требований вы можете решить, в каком формате вы хотите читать ваши файлы YAML. Давайте рассмотрим оба подхода.
Прочитайте файл YAML как карту на Java
Давайте начнем с чтения простого файла YAML в виде набора пар ключ-значение. Файл, который мы будем читать, будет содержать следующие данные:
id: 20 name: Bruce year: 2020 address: Gotham City department: Computer Science
Давайте предположим, что у нас есть этот YAML в папке ресурсов нашего Java-проекта. Давайте сначала загрузим файл в качестве входного потока .
Затем мы создадим экземпляр Yaml , который является отправной точкой для использования библиотеки. Экземпляр Yaml знакомит нас с методами, такими как load () , которые позволяют нам читать и анализировать любой Входной поток , Считыватель или Строку с допустимыми данными YAML:
InputStream inputStream = new FileInputStream(new File("student.yml"));
Yaml yaml = new Yaml();
Map data = yaml.load(inputStream);
System.out.println(data);
Метод возвращает Java Карту , в которой имена свойств используются в качестве ключей против их соответствующих значений.
Обратите внимание , что значения в Карте имеют тип Объект , потому что в файле YAML – мы можем иметь наши данные в виде строковых значений, чисел или даже коллекций. Все это может быть помещено в Объект , поэтому оно включает в себя любое значение, которое мы могли бы ввести.
Если мы напечатаем наш данные объект, в который мы загрузили файл YAML, мы получим следующий результат:
{id=20, name=Bruce, year=2020, address=Gotham City, department=Computer Science}
Как вы можете видеть, свойства из файла YAML просто отображаются в виде пар ключ-значение в объекте карты java.
Давайте обновим наш файл YAML, чтобы он также содержал данные о сборе. Файл обновления YAML выглядит следующим образом:
id: 20
name: Bruce
year: 2020
address: Gotham City
department: Computer Science
courses:
- name: Algorithms
credits: 6
- name: Data Structures
credits: 5
- name: Design Patterns
credits: 3
Теперь наш файл YAML содержит коллекцию курсов , которая имеет несколько значений данных.
Чтобы прочитать обновленный файл YAML, нет необходимости обновлять наш Java-код. Наш предыдущий код сможет успешно загрузить файл YAML в наш объект Map . После прочтения файла результат будет:
{
id=20, name=Bruce, year=2020, address=Gotham City, department=Computer Science,
courses=[{name=Algorithms, credits=6}, {name=Data Structures, credits=5}, {name=Design Patterns, credits=3}]
}
Элемент courses в файле YAML читается как ArrayList , где каждое значение в списке является Картой самим объектом.
Прочитайте объект YAML как пользовательский объект Java
Теперь, когда мы успешно использовали файл YAML в нашем Java-коде в виде простых пар ключ-значение, давайте загрузим тот же файл в качестве пользовательского объекта Java, что является гораздо более распространенным вариантом использования.
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Мы будем использовать следующие классы Java для загрузки данных в наши файлы YAML:
public class Person {
private long id;
private String name;
private String address;
// Getters and setters
}
public class Student extends Person {
private int year;
private String department;
private List courses;
// Getters and setters
}
public class Course {
private String name;
private double credits;
// Getters and setters
}
Мы загрузим данные в объект Student , где элемент courses из файла YAML будет преобразован в Список типа Курс .
Мы будем использовать тот же файл YAML, который мы использовали в предыдущем примере, и загрузим его в качестве входного потока :
InputStream inputStream = new FileInputStream(new File("student_with_courses.yml"));
Yaml yaml = new Yaml(new Constructor(Student.class));
Student data = yaml.load(inputStream);
System.out.println(data);
Теперь, когда мы создаем наш объект класса Yaml , мы указываем тип данных, в который мы хотим преобразовать данные. Новый конструктор(Student.class) говорит SnakeYaml, чтобы он прочитал данные из файла YAML и сопоставил их с нашим объектом Student .
Сопоставление является простым, и имена атрибутов вашего объекта должны совпадать с именами атрибутов YAML ( курсы -> курсы ).
Это приводит к:
Student[Person[id=20, name='Bruce', address='Gotham City'], year=2020, department='Computer Science', courses=[Course[name='Algorithms', credits=6.0], Course[name='Data Structure', credits=5.0], Course[name='Design patters', credits=3.0]]]
Как вы можете видеть, SnakeYaml успешно создал объект Student , сохранив при этом наследование класса Student (Родительский класс Человек ) и связь с классом Курс нетронутыми.
Написание YAML с помощью SnakeYaml
Теперь, когда мы успешно прочитали файлы YAML в нашем Java-коде, давайте начнем записывать данные в файлы YAML с помощью нашего Java-проекта. Аналогично чтению документов YAML, мы можем записать простой Java Map и пользовательский объект Java в файл YAML.
Напишите Карту В YAML
Давайте сначала запишем простой объект Map в файл YAML:
MapdataMap = new HashMap<>(); dataMap.put("id", 19); dataMap.put("name", "John"); dataMap.put("address", "Star City"); dataMap.put("department", "Medical");
Теперь давайте создадим новый объект PrintWriter , имея в виду выходной каталог, и дамп() карту данных , используя этот писатель.
Примечание: Метод dump() принимает любой |/Писатель :
PrintWriter writer = new PrintWriter(new File("./src/main/resources/student_output.yml"));
Yaml yaml = new Yaml();
yaml.dump(dataMap, writer);
В результате получается файл, содержащий:
{address: Star City, name: John, id: 19, department: Medical}
Примечание: заключается в том, что выходной файл YAML не содержит значений в той же последовательности, в которой мы добавили их в наш объект Java Map , поскольку мы использовали HashMap , который не сохраняет порядок ввода.
Вы можете устранить эту проблему, используя вместо этого LinkedHashMap .
Напишите пользовательский объект Java в YAML
Теперь давайте попробуем сохранить наш Студент класс в формате YAML в выходном файле. Для этого мы будем использовать следующий код для настройки объекта Student :
Student student = new Student();
student.setId(21);
student.setName("Tim");
student.setAddress("Night City");
student.setYear(2077);
student.setDepartment("Cyberware");
Course courseOne = new Course();
courseOne.setName("Intelligence");
courseOne.setCredits(5);
Course courseTwo = new Course();
courseTwo.setName("Crafting");
courseTwo.setCredits(2);
List courseList = new ArrayList<>();
courseList.add(courseOne);
courseList.add(courseTwo);
student.setCourses(courseList);
Теперь давайте используем наш экземпляр Yaml с реализацией Writer для дампа() данных в файл:
PrintWriter writer = new PrintWriter(new File("./src/main/resources/student_output_bean.yml"));
Yaml yaml = new Yaml();
yaml.dump(student, writer);
Это приводит к:
!!model.Student
address: Night City
courses:
- {credits: 5.0, name: Intelligence}
- {credits: 2.0, name: Crafting}
department: Cyberware
id: 21
name: Tim
year: 2077
Если вы внимательно посмотрите на выходные файлы YAML, сгенерированные нашим кодом, вы увидите, что в первом примере все данные были сброшены в одну строку, тогда как во втором примере значения Курс объекта записаны в одной строке каждый под элементом курсы.
Хотя оба сгенерированных выходных файла имеют допустимый синтаксис YAML, если вы хотите создать файл YAML в более часто используемом формате, где каждое значение записывается в одну строку и в скобках нет, вы можете настроить объект DumperOptions и передать его в конструктор Yaml :
DumperOptions options = new DumperOptions(); options.setIndent(2); options.setPrettyFlow(true); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); Yaml yaml = new Yaml(options);
Здесь мы указали отступ и поток документов YAML, используя объект DumperOptions . Теперь, когда мы используем функцию dump в экземпляре Yaml , мы получим вывод в другом формате:
!!model.Student address: Night City courses: - credits: 5.0 name: Intelligence - credits: 2.0 name: Crafting department: Cyberware id: 21 name: Tim year: 2077
Вывод
Поскольку файлы YAML используются все чаще, особенно для указания свойств проекта и метаданных сборки и развертывания, становится все более полезным иметь возможность обрабатывать их с помощью кода.
С помощью SnakeYaml мы можем легко управлять файлами YAML в нашем проекте Java, и минимальный объем кода используется либо для загрузки файлов YAML в наш проект, либо для записи данных в файлы YAML. SnakeYaml также предоставляет параметры форматирования, чтобы вы могли настраивать и настраивать их в соответствии с вашими потребностями.
Исходный код для примера кода можно найти на GitHub .