← Назад к вопросам
Как реализовать валидацию входящего запроса в Spring?
2.2 Middle🔥 281 комментариев
#REST API и микросервисы#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Валидация входящего запроса в Spring
Spring Framework предоставляет мощный механизм валидации данных, основанный на Bean Validation (JSR-380). Существует несколько подходов для валидации входящих запросов.
1. Аннотации Bean Validation
Bean Validation использует аннотации для описания правил валидации на уровне модели данных:
import jakarta.validation.constraints.*;
public class UserRequest {
@NotBlank(message = "Имя не может быть пустым")
@Size(min = 2, max = 50, message = "Имя должно быть от 2 до 50 символов")
private String name;
@Email(message = "Email должен быть валидным")
@NotNull(message = "Email не может быть null")
private String email;
@Min(value = 18, message = "Минимальный возраст 18 лет")
@Max(value = 120, message = "Максимальный возраст 120 лет")
private Integer age;
@Pattern(regexp = "^\\d{10}$", message = "Телефон должен содержать 10 цифр")
private String phone;
}
2. Использование @Valid в контроллере
Аннотация @Valid активирует валидацию параметра перед входом в метод:
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<?> createUser(@Valid @RequestBody UserRequest request) {
// Если валидация не пройдена, будет выброшено исключение
// MethodArgumentNotValidException
return ResponseEntity.ok("User created");
}
}
3. Обработка ошибок валидации
Для красивой обработки ошибок используется ControllerAdvice с аннотацией @ExceptionHandler:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleValidationException(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage())
);
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(errors);
}
}
4. Кастомные аннотации валидации
Можно создать собственные аннотации для специфических правил:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
String message() default "Некорректный номер телефона";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) return true;
return value.matches("^\\d{10}$");
}
}
5. Программная валидация
Некоторые сценарии требуют программной валидации:
@Service
public class UserService {
private final Validator validator;
public void validateUser(UserRequest request) {
Set<ConstraintViolation<UserRequest>> violations =
validator.validate(request);
if (!violations.isEmpty()) {
violations.forEach(v ->
System.out.println(v.getPropertyPath() + ": " + v.getMessage())
);
throw new ValidationException("Валидация не пройдена");
}
}
}
6. Валидация на уровне сервиса
Для более сложной бизнес-логики валидация может быть в сервисном слое:
@Service
public class UserService {
private final UserRepository repository;
public void createUser(UserRequest request) {
// Проверка уникальности email
if (repository.existsByEmail(request.getEmail())) {
throw new ValidationException("Email уже зарегистрирован");
}
// Остальная логика
}
}
Лучшие практики
- Простая валидация (формат, длина) → аннотации Bean Validation
- Комплексная валидация (проверка уникальности) → сервисный слой
- Обработка ошибок → ControllerAdvice
- Переиспользуемые правила → кастомные аннотации
- Группы валидации → для разных сценариев (создание, обновление)