Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Проверка данных

Сейчас API примет статью с пустым заголовком или вовсе без текста. Валидация — проверка входных данных до того, как они попадут в логику приложения. Правила записывают аннотациями стандарта Jakarta Validation прямо на полях записи, а Micronaut проверяет их и при нарушении отвечает 400 с понятным списком ошибок.

Подключение

Если вы не выбрали возможность validation в генераторе, добавьте её вручную. Что именно добавить, покажет команда mn feature-diff --features=validation в папке проекта. В pom.xml нужны две зависимости:

<!-- pom.xml, внутри <dependencies> -->
<dependency>
  <groupId>io.micronaut.validation</groupId>
  <artifactId>micronaut-validation</artifactId>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>jakarta.validation</groupId>
  <artifactId>jakarta.validation-api</artifactId>
  <scope>compile</scope>
</dependency>

И обработчик аннотаций — в настройки maven-compiler-plugin, рядом с уже имеющимися <path>:

<!-- pom.xml, внутри <annotationProcessorPaths> -->
<path>
  <groupId>io.micronaut.validation</groupId>
  <artifactId>micronaut-validation-processor</artifactId>
  <version>${micronaut.validation.version}</version>
  <exclusions>
    <exclusion>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-inject</artifactId>
    </exclusion>
  </exclusions>
</path>

После изменения обработчиков пересоберите проект целиком: ./mvnw clean compile.

Правила на записи

// src/main/java/com/example/ArticleForm.java
package com.example;
 
import io.micronaut.serde.annotation.Serdeable;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
 
@Serdeable
public record ArticleForm(
        @NotBlank @Size(max = 100) String title,
        @NotBlank String body) {
}
АннотацияЧто проверяет
@NotNullЗначение не null
@NotBlankСтрока не пустая и не из одних пробелов
@Size(min, max)Длина строки или размер списка
@Min, @MaxГраницы числа
@EmailПохоже на адрес почты

Включение в контроллере

Поставьте @Valid перед параметром метода в ArticleController:

// src/main/java/com/example/ArticleController.java
@Post
public HttpResponse<Article> create(@Body @Valid ArticleForm form) {
    Article article = articleService.create(form);
    return HttpResponse.created(article, URI.create("/articles/" + article.id()));
}

@Valid импортируется из jakarta.validation. Обработчик аннотаций видит его и ещё при компиляции оборачивает метод проверкой — во время работы рефлексия не нужна.

Проверка

curl -i -X POST http://localhost:8080/articles \
  -H "Content-Type: application/json" \
  -d '{"body":""}'
HTTP/1.1 400 Bad Request
Content-Type: application/json
 
{"_links":{"self":[{"href":"/articles","templated":false}]},"_embedded":{"errors":[{"message":"form.body: must not be blank"},{"message":"form.title: must not be blank"}]},"message":"Bad Request"}

Каждое нарушение — отдельный элемент errors с именем параметра и поля. Корректный запрос по-прежнему создаёт статью с ответом 201. Аннотации работают и в сервисах: @Valid или @NotBlank на параметре метода любого бина тоже включает проверку.

Частая ошибка

Самая коварная ошибка — правила есть, но не срабатывают: статья с пустым заголовком сохраняется с ответом 201. Причин две. Либо не подключён micronaut-validation-processor, либо проект не пересобран после его добавления — старые классы скомпилированы без проверки. Убедитесь, что обработчик есть в <annotationProcessorPaths>, и выполните ./mvnw clean compile. Признак, что всё в порядке: в target/classes/com/example/ появился класс $ArticleController$Definition$Intercepted.class.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.