Валідація "без участі людини" — це як мати сумлінного робота, який перевіряє твою пошту перед тим, як ти її читаєш: сміття відкидає, важливі листи позначає. Аналогічно, анотація @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"
}
Часті помилки
- Відсутність залежності Bean Validation у
pom.xml. У проєкті може бракувати потрібної залежності. Переконайся, що в твоємуpom.xmlдодано модуль Bean Validation:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> - Тіло запиту не перетворюється у DTO. Якщо ти забув вказати
@RequestBody, JSON просто не буде розпізнано. Завжди пам'ятай про цю анотацію. - Неправильний імпорт анотації
@Valid. Переконайся, що використовуєшjakarta.validation.Valid(абоjavax.validation.Validу старих версіях), а не щось із сторонніх бібліотек. - Забута обробка виключень. Spring може викинути виключення
MethodArgumentNotValidException, яке, якщо його не обробити, призведе до некрасивих і заплутаних повідомлень для користувача.
Практичне застосування
Валідація через @Valid широко використовується в реальних проєктах для:
- Автоматичної перевірки даних, що надходять від клієнтів.
- Запобігання помилкам на ранньому етапі, до потрапляння даних у бізнес-логіку або в базу.
- Покращення читабельності та підтримуваності коду.
На співбесідах тебе можуть попросити описати, як ти реалізуєш валідацію в Spring, а ще краще — написати просту REST-операцію з @Valid. Знання цього інструменту дасть тобі серйозну перевагу.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ