middle
Как работает валидация в Spring? Что такое @Valid и @Validated?
Spring интегрирует Bean Validation API (JSR 380) через Hibernate Validator для декларативной валидации данных. Аннотация @Valid перед @RequestBody активирует проверку.
Основные аннотации валидации
Пример
public class CreateUserRequest {
@NotBlank(message = "Имя не может быть пустым")
@Size(min = 2, max = 100)
private String firstName;
@NotBlank @Email
private String email;
@NotNull @Min(18) @Max(150)
private Integer age;
@Positive
private BigDecimal balance;
@Pattern(regexp = "^\\+7\\d{10}$")
private String phone;
@Past
private LocalDate birthDate;
@Valid @NotNull // каскадная валидация вложенного объекта
private AddressDto address;
}
Применение
Пример
@PostMapping
public ResponseEntity<UserDto> createUser(@Valid @RequestBody CreateUserRequest request) {
// Если валидация не пройдена -- MethodArgumentNotValidException (400)
return ResponseEntity.status(HttpStatus.CREATED).body(userService.create(request));
}
@Valid vs @Validated
| Аспект | @Valid (javax) | @Validated (Spring) |
|---|---|---|
| Группы валидации | Нет | Да |
| На уровне класса | Нет | Да |
| Каскадная валидация | Да | Да |
Группы валидации
Пример
public interface OnCreate {}
public interface OnUpdate {}
public class UserRequest {
@Null(groups = OnCreate.class)
@NotNull(groups = OnUpdate.class)
private Long id;
}
@PostMapping
public UserDto create(@Validated(OnCreate.class) @RequestBody UserRequest request) { }
@PutMapping("/{id}")
public UserDto update(@Validated(OnUpdate.class) @RequestBody UserRequest request) { }
На собеседовании: ключевое – разница между
@Validи@Validated(группы валидации). Частая ошибка – забыть@Validперед@RequestBody(валидация не выполнится). Также – не добавитьspring-boot-starter-validation(в Spring Boot 3 он не входит в starter-web).