Ответ
Валидация на уровне контроллера — это практика проверки корректности входящих HTTP-запросов (тела, параметров, заголовков) непосредственно в точке входа, до передачи данных в сервисный слой.
Реализация в Spring (с использованием Bean Validation):
- Аннотируйте DTO-объект ограничениями из
jakarta.validation(илиjavax.validation). - Используйте аннотацию
@Valid(или@Validated) перед параметром метода контроллера.
Пример:
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody UserCreateRequest request) {
// Бизнес-логика выполняется только после успешной валидации
return ResponseEntity.ok(userService.create(request));
}
}
// DTO с ограничениями
public class UserCreateRequest {
@NotNull
@Size(min = 2, max = 100)
private String name;
@NotNull
@Email
private String email;
@Min(18)
private Integer age;
// getters/setters
}
Что происходит при ошибке?
Spring выбрасывает исключение MethodArgumentNotValidException. Его обычно обрабатывают в @ControllerAdvice, возвращая клиенту структурированное сообщение об ошибках.
Преимущества:
- Ранний отказ: Некорректные данные отсекаются сразу.
- Чистота сервисов: Бизнес-логика не засоряется проверками входных данных.
- Стандартизация: Единый механизм валидации для всех контроллеров.
Ответ 18+ 🔞
Слушай, а вот есть такая штука — валидация на уровне контроллера. Ну, это когда ты проверяешь, что тебе прилетело в HTTP-запросе, прямо на входе, блядь, пока ещё эти данные не уползли в сервисы и не начали там какую-то дичь творить.
В Спринге это делается проще пареной репы, если использовать Bean Validation. Сейчас объясню на пальцах, ёпта.
Вот смотри: берёшь свой DTO, этот... объект, в который данные мапятся. И начинаешь его разрисовывать аннотациями из jakarta.validation. Типа, «эй, поле, ты не должно быть пустым» или «эй, почта, будь добр, выгляди как почта, а не как набор случайных символов».
Потом в контроллере, перед параметром, куда этот DTO прилетает, ставишь волшебную аннотацию @Valid. И всё, блядь! Спринг сам всё проверит. Если данные — говно, то в сервисный слой они даже не пролезут, их нахуй завернут обратно.
Вот, смотри пример, чтобы совсем понятно было:
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody UserCreateRequest request) {
// Сюда выполнение дойдёт только если валидация прошла. Иначе — пиздец и исключение.
return ResponseEntity.ok(userService.create(request));
}
}
// А это сам DTO, наш подопытный кролик
public class UserCreateRequest {
@NotNull // Не хуй тут будет null!
@Size(min = 2, max = 100) // И длинна от 2 до 100 символов, блядь
private String name;
@NotNull
@Email // Это чтоб реальная почта была, а не "вася@пук.сом"
private String email;
@Min(18) // Меньше 18? Иди нахуй, взрослей сначала.
private Integer age;
// геттеры/сеттеры тут
}
А что, если данные всё-таки кривые?
О, тут интересно! Спринг, такой весь из себя принципиальный, выкинет исключение MethodArgumentNotValidException. Его обычно ловят в каком-нибудь @ControllerAdvice, разбирают на запчасти и отправляют клиенту красивый, структурированный ответ, типа: «дружище, у тебя тут три ошибки, вот они, исправляй».
И зачем этот цирк, спросишь? А преимущества-то, блядь, овердохуищные:
- Ранний отказ. Неправильные данные отшибаются на самом пороге. Зачем их тащить дальше, тратить ресурсы?
- Чистота в сервисах. Твоя бизнес-логика не засрана тысячей
if-elseна проверку входящего говна. Она занимается своим делом. - Стандартизация. Один раз настроил — и все контроллеры работают по одному сценарию. Красота, ёпта!
В общем, вещь полезная. Не пренебрегай, а то потом будешь в сервисах ошибки ловить, которые можно было отсечь ещё на подходе.