JavaRush /Курси /Модуль 5. Spring /Використання анотації @Valid для валідації запитів

Використання анотації @Valid для валідації запитів

Модуль 5. Spring
Рівень 8 , Лекція 2
Відкрита

Валідація "без участі людини" — це як мати сумлінного робота, який перевіряє твою пошту перед тим, як ти її читаєш: сміття відкидає, важливі листи позначає. Аналогічно, анотація @Valid дозволяє автоматизувати перевірку вхідних даних у твоїх контролерах і сервісах.

Основні аспекти @Valid

  • Вона є частиною специфікації Bean Validation API.
  • Автоматично перевіряє, чи відповідають вхідні дані анотаціям валідації, оголошеним у DTO (Data Transfer Object) або в інших об'єктах.
  • Допомагає спростити й централізувати валідацію даних, зберігаючи твій код чистим і читабельним.

Простіший приклад: ти приймаєш JSON як тіло POST-запиту, і тобі потрібно, щоб поле "email" було обов'язковим і відповідало формату email. Замість ручної перевірки (наприклад, через if) за допомогою @Valid і кількох анотацій валідації все це обробляється автоматично.


Як використовувати @Valid в контролерах?

Крок 1. Оголошення DTO

Почнемо зі створення DTO-класу. DTO (Data Transfer Object) — це об'єкт, що використовується для передачі даних, наприклад від клієнта до сервера.


import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

public class UserDTO {

    @NotNull(message = "Ім'я користувача не може бути порожнім.")
    @Size(min = 2, max = 30, message = "Ім'я користувача повинно містити від 2 до 30 символів.")
    private String username;

    @NotNull(message = "Email обов'язковий.")
    @Email(message = "Некоректний формат email.")
    private String email;

    public UserDTO() {}

    public UserDTO(String username, String email) {
        this.username = username;
        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Тут ми використовуємо:

  • @NotNull — щоб переконатися, що поле не порожнє.
  • @Size — щоб обмежити довжину рядка.
  • @Email — щоб перевірити, що email коректний.

З полем розібралися! Переходимо до наступного кроку.

Крок 2. Створення REST-контролера

Тепер використаємо анотацію @Valid в контролері для автоматичної перевірки вхідних даних.


import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        // Якщо дані валідні, виконання доходить сюди.
        return new ResponseEntity<>("Користувач успішно створений", HttpStatus.CREATED);
    }
}
  • @RestController вказує, що цей клас — REST-контролер.
  • @RequestBody — перетворює JSON в об'єкт UserDTO.
  • @Valid — запускає валідацію, яка перевіряє поля UserDTO.

Якщо вхідні дані валідні, тіло запиту успішно перетворюється в об'єкт, і сервер повертає HTTP 201 (Created). Якщо валідація не пройшла, Spring автоматично викине виключення MethodArgumentNotValidException.

Крок 3. Додавання користувацьких повідомлень

Кожна анотація валідації в UserDTO містить параметр message, який вказує текст помилки. Наприклад, якщо поле email не відповідає формату, клієнт отримає повідомлення "Некоректний формат email.".


Приклад застосунку з використанням @Valid

Зберемо все в один невеликий застосунок.

Основний код застосунку

DTO:


public class UserDTO {
    @NotNull(message = "Ім'я користувача не може бути порожнім.")
    @Size(min = 2, max = 30, message = "Ім'я користувача повинно містити від 2 до 30 символів.")
    private String username;

    @NotNull(message = "Email обов'язковий.")
    @Email(message = "Некоректний формат email.")
    private String email;

    // Геттери, сеттери і конструктор
}

Controller:


@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        return new ResponseEntity<>("Користувач успішно створений", HttpStatus.CREATED);
    }
}

application.properties:


server.port=8080

Що, якщо дані не валідні?

Під час відправки некоректних даних Spring автоматично поверне HTTP 400 (Bad Request) з повідомленням про помилку в форматі JSON:


{
    "timestamp": "2023-10-01T12:34:56.789+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "Некоректний формат email.",
    "path": "/api/users"
}

Часті помилки

  1. Відсутність залежності Bean Validation у pom.xml. У проєкті може бракувати потрібної залежності. Переконайся, що в твоєму pom.xml додано модуль Bean Validation:
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    
  2. Тіло запиту не перетворюється у DTO. Якщо ти забув вказати @RequestBody, JSON просто не буде розпізнано. Завжди пам'ятай про цю анотацію.
  3. Неправильний імпорт анотації @Valid. Переконайся, що використовуєш jakarta.validation.Valid (або javax.validation.Valid у старих версіях), а не щось із сторонніх бібліотек.
  4. Забута обробка виключень. Spring може викинути виключення MethodArgumentNotValidException, яке, якщо його не обробити, призведе до некрасивих і заплутаних повідомлень для користувача.

Практичне застосування

Валідація через @Valid широко використовується в реальних проєктах для:

  • Автоматичної перевірки даних, що надходять від клієнтів.
  • Запобігання помилкам на ранньому етапі, до потрапляння даних у бізнес-логіку або в базу.
  • Покращення читабельності та підтримуваності коду.

На співбесідах тебе можуть попросити описати, як ти реалізуєш валідацію в Spring, а ще краще — написати просту REST-операцію з @Valid. Знання цього інструменту дасть тобі серйозну перевагу.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ