BindingResult
🚫 주의!
BindingResult는 순서가 매우 중요
Model에 자동으로 포함
FieldError, ObjectError
사용자 입력 오류 값을 필드에 그대로 남기려면 ⁉️
사용자의 입력 데이터가 컨트롤러의 @ModelAttribute에 바인딩되는 시점에 오류가 발생하면 모델 객체에 사용자 입력값을 유지하기 어렵다.(ex 숫자 필드에 문자열)
스프링은 HTTP 요청이 넘어올 때 requestParameter 값을 꺼내고 바인딩이 실패했을 경우 FieldError를 만듦 -> 바인딩 실패 값을 rejectedValue에 값을 넣음, 바인딩 실패 구분값은 true -> BindingResult에 담아 컨트롤러 호출
오류코드와 메세지 처리
BindingResult는 객체 뒤에 바로 붙기 때문에 어떤 객체를 대상으로 검사하는지 이미 알고 있음.
오류 코드를 단순하게 만들면 범용성이 좋아서 여러곳에서 사용할 수 있지만 세밀하게 작성하긴 어렵다. 반대로 너무 자세하게 만들면 범용성이 떨어진다.
#Level1
required.item.itemName=상품 이름은 필수입니다.
#Level2
required=필수 값입니다.
가장 좋은 방법은 💡범용성으로 사용하다가, 세밀하게 작성해야하는 경우 세밀한 내용이 적용되도록 단계를 두는 방법이다. (객체와 필드명을 조합한 에러코드가 있으면 그게 1순위, 그냥 에러코드가 2순위)
스프링은 MessageCodesResolver라는 것으로 이런 기능을 지원함 ✨
BindingResult가 rejectValue 실행시 내부에서 MessageCodesResolver를 사용 -> 생성된 에러코드 배열을 FieldError에 생성자로 넘김
스프링이 직접 만든 오류 메시지 처리
typeMismatch 추가
Validator 분리
스프링은 Validator라는 인터페이스를 제공
WebDataBinder 사용하기 : 스프링 파라미터 바인딩의 역할을 해주고 검증기능도 내부에 포함된다
@InitBinder
public void init(WebDataBinder dataBinder) {
dataBinder.addValidators(itemValidator);
}
컨트롤러 실행 시 항상 검증기를 적용할 수 있음
public String test(@Validated @ModelAttribute Item item, BindingResult bindingResult)
@Validated 어노테이션을 넣으면 Item이라는 객체에 대해 자동으로 검증기 수행, bindingResult에 결과 담김
@Validated : 검증기를 실행하라는 어노테이션
이 어노테이션이 붙으면 앞서 WebDataBinder에 등록한 검증기를 찾아서 실행한다. 만약 여러 검증기를 등록한다면 어떤 검증기를 실행해야할지 구분이 필요하기 때문에 이때 supports() 함수를 사용한다! (이 과정은 스프링이 자동화해줌)
메인 클래스에 WebMvcConfigurer를 상속받아 getValidator() 오버라이딩
(@InitBinder를 제거해도 검증기 정상 동작)
🙋♀️참고
@Valid는 자바 표준 검증 어노테이션
@Validator는 스프링 전용 검증 어노테이션