Введение в записи
Java 14 была выпущена в марте 2020 года, и одной из функций, которая привлекла наше внимание, были записи. Давайте начнем с объяснения того, что такое запись, а затем перейдем к потенциальным вариантам использования.
Примечание: Скоро выйдет Java 17 (сентябрь 2021 года), которая является первой версией LTS с поддержкой записей.
Из Openjdk JEP359:
Записи обеспечивают компактный синтаксис для объявления классов, которые являются прозрачными держателями неглубоко неизменяемых данных.
Эта функция пытается уменьшить объем шаблонного кода в наших приложениях, так как вам нужно только определить поля (эквивалентно полям класса). Записи предоставляют общедоступный конструктор (со всеми аргументами), методы чтения для каждого поля (эквивалентные получателям) и реализацию методов hashCode, equals и toString.
Вот как будут выглядеть запись и класс для одной и той же структуры данных.
Запись
public record Person(String name, int age) { }
Класс
public class Person { private String name; private int age; public Person(String name, int age) { ... } public boolean equals(Object o) { ... } public int hashCode() { ... } public String toString() { ... } }
Как вы заметите, это значительно меньше кода, учитывая полезность класса.
Обычаи
Так где же тогда можно было бы использовать эти Записи? Одно из потенциальных применений находится в контроллерах rest. Иногда бывает довольно неприятно создавать класс только для использования в качестве возвращаемого типа или тела запроса в контроллере rest.
В следующем разделе мы продемонстрируем, как создать api spring boot rest с записями.
Демонстрация
Код для этой демонстрации можно найти здесь:
psideris89/java-записи-демо
Демонстрационный api spring boot rest для демонстрации записей java 14
Шаг 1: Создайте приложение Spring Boot
Вы можете использовать инициализатор пружины ( https://start.spring.io/ ) для создания проекта spring boot. Конфигурация для нашей демо-версии такова:
- Проект: Градация
- Язык: Java 16
- Пружинный ботинок: 2.5.4
- Название: фильмы-демо
- Зависимости: Весенняя паутина
Все остальное можно было бы оставить со значением по умолчанию.
Шаг 2: Конфигурация проекта
Если вы используете IDE, вам необходимо использовать jdk 16. Для Intellij установите project sdk в 16 и языковой уровень проекта для 16 .
Устаревшая конфигурация (java 14)
Если вы используете java 16, вы можете пропустить этот раздел.
Чтобы использовать записи с jdk 14, необходимо включить функции предварительного просмотра. Вам может быть предложено принять некоторые условия, если вы хотите использовать функции предварительного просмотра, поэтому нажмите “Принять” и продолжайте.
Кроме того, добавьте следующую конфигурацию в build.gradle . Аналогичная конфигурация существует и для maven.
compileJava { options.compilerArgs += ["--enable-preview"] } test { jvmArgs(['--enable-preview']) }
Шаг 3: Создайте контроллер Rest
Прежде чем мы создадим контроллер rest, нам нужно определить записи.
Директор
public record Director(String name, String surname) { }
Кино
public record Movie(String id, Director director, Boolean released) { }
Затем создайте контроллер rest с 3 конечными точками: одна для извлечения всех фильмов, другая для извлечения фильма по идентификатору и последняя для добавления фильма (на самом деле мы ничего не сохраняем, так как это для демонстрации десериализации).
@RestController public class MoviesController { private Listmovies = List.of( new Movie("1", new Director("John", "Wick"), true), new Movie("2", new Director("Mary", "Poppins"), false), new Movie("3", new Director("Jack", "Sparrow"), true), new Movie("4", null, false)); @GetMapping("/movies") public List getMovies() { return movies; } @GetMapping("/movies/{id}") public Movie getMovie(@PathVariable String id) { return movies .stream() .filter(s -> s.id().equals(id)) .findFirst() .orElseThrow(() -> new RuntimeException("Not found")); } @PostMapping("/movies") public Movie addMovie(@RequestBody Movie movie) { // Save the movie, be careful as List.of() is immutable return movie; } }
Шаг 4: Настройте Джексона для сериализации/десериализации
Запустите приложение и вызовите первую конечную точку, локальный хост: 8080/фильмы . Следующая ошибка возникает, так как объекты не могут быть сериализованы.
Решение этой проблемы заключается в использовании аннотаций Джексона и в конкретных аннотациях JsonProperty .
public record Director(@JsonProperty("name")String name, @JsonProperty("surname")String surname) { } public record Movie(@JsonProperty("id") String id, @JsonProperty("director") Director director, @JsonProperty("released") Boolean released) { }
Перезапустите приложение, и вы сможете получить список фильмов.
Конечная точка getMovie ( локальный хост:8080/фильмы/1 ) использует метод id() , который предоставляется Записью. Таким образом, мы можем сравнить идентификатор каждого фильма с идентификатором, предоставленным в вызове api.
Наконец, конечная точка addMovie – это просто макет конечной точки, но это доказывает, что десериализация также работает. Чтобы проверить это, вам нужно отправить запрос на localhost:8080/фильмы с действительным телом.
{ "id": "10", "director": { "name": "Jim", "surname": "White" }, "released": false }
Вывод
Что могут означать записи для будущего java? Возможно, они не предназначены для использования таким образом, но в целом эта функция – то, что ожидали многие разработчики java. Тот факт, что записи неизменяемы, добавляет огромную ценность. Все вышеперечисленное в сочетании с сокращением шаблонного кода делает записи многообещающей функцией.
Оригинал: “https://dev.to/psideris89/java-14-records-in-spring-boot-rest-api-n29”