12-2. WebDataBinder → SmartValidator: validate() (@Valid 검증)
DTO 생성이 끝나면, Spring은 WebDataBinder와 SmartValidator를 사용해 @Valid 검증을 수행합니다.
이번 단계의 역할 — 역직렬화된 객체가 컨트롤러에 들어가기 전 유효한지 검사한다
역직렬화된 객체가 컨트롤러에 들어가기 전에 유효한지 검사하는 단계입니다.
호출 흐름 요약 — createBinder() → validateIfApplicable() → binder.validate()
RequestResponseBodyMethodProcessor가WebDataBinder를 생성합니다.validateIfApplicable(...)가 검증 어노테이션을 확인합니다.binder.validate(...)가SmartValidator로 위임됩니다.BindingResult에 오류가 쌓입니다.- 오류가 있으면
MethodArgumentNotValidException으로 전환됩니다.
호출 흐름 다이어그램 — WebDataBinder가 SmartValidator로 위임하고 결과는 BindingResult에 쌓인다
sequenceDiagram
participant RR as RequestResponseBodyMethodProcessor
participant BF as WebDataBinderFactory
participant Binder as WebDataBinder
participant Validator as SmartValidator
participant BR as BindingResult
RR->>BF: createBinder(...)
BF-->>RR: WebDataBinder
RR->>Binder: validate(...)
Binder->>Validator: validate(target, errors)
Validator-->>BR: violation info
핵심 코드 — validateIfApplicable() 실패는 MethodArgumentNotValidException으로 던져진다
// 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());
}
}
코드 해설 — JSON 파싱이 성공한 뒤에만 검증이 돌고 결과는 BindingResult에 모인다
역직렬화와 검증이 분리되어 있기 때문에, JSON 파싱이 성공한 뒤에만 검증이 진행됩니다.
또한 검증 결과는 BindingResult라는 표준 결과 객체에 쌓입니다.
설계 의도 — 바인딩 결과와 검증 결과를 BindingResult 한 곳에 모은다
바인딩 결과와 검증 결과를 같은 컨테이너(BindingResult)에 모아, 컨트롤러 진입 전 오류 여부를 일관되게 판단하기 위한 구조입니다.
다음 단계 연결 — 12-3 검증 오류가 예외 처리 체인으로 넘어가는 과정으로 이어진다
다음 문서 12-3에서는 이 검증 오류가 DispatcherServlet의 예외 처리 체인으로 어떻게 넘어가는지 봅니다.
← 이전: 12-1. AbstractJackson2HttpMessageConverter → ObjectMapper | 다음: 12-3. DispatcherServlet → ExceptionHandler