← Назад к вопросам

Как реализовать валидацию входящего запроса в 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
  • Переиспользуемые правила → кастомные аннотации
  • Группы валидации → для разных сценариев (создание, обновление)
Как реализовать валидацию входящего запроса в Spring? | PrepBro