Автор оригинала: 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(); Mapdata = 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 Listcourses; // 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); ListcourseList = 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 .