Введение в записи
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 List movies = 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”