검증 어노테이션과 여러 인터페이스의 모음
일반적으로 하이버네이트 Validator를 구현체로 사용
공식 문서
build.gradle에 의존관계추가
implementation 'org.springframework.boot:spring-boot-starter-validation'
스프링에선 빈 검증기를 완전히 통합해뒀음
implementation 'org.springframework.boot:spring-boot-starter-validation'이 있으면, 자동으로 통합
글로벌 Validator를 등록하기 때문에, @Validated만 적용하면 됨
오류가 나면, filedError,ObjectError를 생성해서 BindingResult에 담아줌
검증 순서
1.@ModelAttriburte로 각각의 필드에 타입 변환 시도
typeMismatch로 FieldError 추가2.Validator 적용 (변환에 성공한 필드만)
오류코드는 기본적으로 어노테이션 이름으로 등록된다.
오류코드를 기반으로 MessageCodesResolver를 통해 생성됨
글로벌(오브젝트) 오류
@ScriptAssert를 사용하는 방법도 있지만, 기능이 약하므로
오브젝트 오류 관련은 자바로 작성 권장
동일한 모델 객체를 등록할 때와 수정할 때 요구사항이 다를 수 있다.
해결방법2가지
인터페이스를 만들고, 어노테이션을 쓸 인터페이스를 지정해준다.
@NotBlank(groups = {SaveCheck.class, UpdateCheck.class})
@Validate에, 인터페이스를 넘겨주면, 해당 인터페이스가 지정됬을때만 검사한다
public String edit2(@PathVariable Long itemId, @Validated(UpdateCheck.class) @ModelAttribute Item item, BindingResult bindingResult)
groups 기능은 실제 잘 사용되지 않는다
실무에서는 groups를 잘 사용하지 않는다.
등록시 폼에서 전달하는 데이터가, 도메인 객체와 딱 맞지 않기 때문이다.
그래서 보통 객체를 직접 전달받지 않고, 폼의 데이터를 컨트롤러까지 전달할 별도의 객체를 만들어서 전달한다.
Item 도메인 객체 사용
HTML form => Item => Controller => Item => Repository
폼만을 위한 별도의 객체 사용
HTML form => ItemsaveForm => Controller => Item 생성 => Repository
실무에서는 거의 이 방식을 쓴다
Validated는 HttpMessageConverter(@RequestBody)에도 적용 가능
API 3가지 경우
ModelAttributes vs RequestBody
ModelAttributes
RequestBody
HttpMessageConverter에서 Json을 객체로 변경하지 못하면 바로 예외