12-2. WebDataBinder → SmartValidator: validate() (@Valid 검증)
Step 12-1에서 DTO 생성이 성공하면, 다음은 Bean Validation 단계입니다. RequestResponseBodyMethodProcessor는 WebDataBinder를 만들고, 검증 어노테이션이 있으면 validate를 실행합니다.
시퀀스 다이어그램
sequenceDiagram
participant RR as RequestResponseBodyMethodProcessor
participant BF as WebDataBinderFactory
participant Binder as WebDataBinder
participant Validator as SmartValidator
participant BR as BindingResult
RR->>BF: createBinder(webRequest, arg, name, type)
BF-->>RR: WebDataBinder
RR->>RR: validateIfApplicable(binder, parameter)
RR->>Binder: validate(...)
Binder->>Validator: validate(target, errors)
Validator-->>Binder: 제약조건 위반 반영
Binder-->>RR: BindingResult 보유
RR->>BR: hasErrors() 검사
핵심 코드 흐름
// RequestResponseBodyMethodProcessor.java
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name, type);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
validateIfApplicable는 @Valid, @Validated 같은 검증 트리거 어노테이션을 읽어 binder.validate(…)를 호출합니다.
DataBinder 관점에서 보기
DataBinder는 바인딩 결과와 검증 결과를 BindingResult에 축적합니다. 핵심은 검증 실패가 “예외 전환 조건”으로 연결된다는 점입니다.
- 오류 없음: 컨트롤러 파라미터로 전달
- 오류 있음 + BindException 필요: MethodArgumentNotValidException 발생
설계 포인트
- 역직렬화와 검증을 분리하여 책임을 명확히 유지
- BindingResult라는 표준 결과 객체에 오류를 누적
- 컨트롤러 진입 전 실패를 확정하여 비즈니스 로직 오염 최소화
탐구 질문
- DTO 필드 제약(@NotNull, @Size)과 도메인 규칙(Service 계층 검증)은 어떻게 분리하는 것이 좋을까요?
- @Valid를 빼면 어떤 문제가 생길까요?
- BindingResult를 컨트롤러 파라미터로 직접 받는 방식과 예외 기반 처리 방식은 어떤 트레이드오프가 있을까요?