검증 로직의 기술 표준, 검증 애노테이션과 여러 인터페이스의 모음이다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
의존 관계를 추가하여 사용할 수 있다.
검증 애노테이션 예)
@NotBlank : 빈값 + 공백만 있는 경우를 허용하지 않는다. @NotNull : null 을 허용하지 않는다. @Range(min = 1000, max = 1000000) : 범위 안의 값이어야 한다. @Max(9999) : 최대 9999까지만 허용한다.LocalValidatorFactoryBean 을 글로벌 Validator로 등록하기 때문에 @Valid, @Validated 만 적용하면 된다. Validator는 @NotNull 같은 애노테이션을 보고 검증을 수행한다. FieldError , ObjectError 를 생성해서 BindingResult 에 담아준다.BeanValidator는 바인딩에 실패한 필드는 BeanValidation을 적용하지 않는다
Bean Validation이 기본으로 제공하는 오류 메시지를 변경하고 싶은 경우? => 해당 코드를 errors.properties에 등록한다.
예시 ) NotBlank의 오류 코드
(MessageCodesResolver 를 통해 다양한 메시지 코드가 순서대로 생성된다.)
@NotBlank
NotBlank.item.itemName
NotBlank.itemName
NotBlank.java.lang.String
NotBlank
messageSource 에서 메시지 찾기 @NotBlank(message = "공백! {0}") 특정 필드가 아닌 해당 오브젝트 관련 오류는 어떻게 해결?
검증하고자 하는 클래스 위에 애노테이션을 작성한다.
문제점
실무에서는 컨트롤러 단에 직접 코드를 추가해 검증하는 방식을 많이 쓴다.
@PostMapping("/add")
public String addItem(@Validated @ModelAttribute Item item, BindingResult
bindingResult, RedirectAttributes redirectAttributes) {
데이터를 등록할 때와 수정할 때는 요구사항이 다를 수 있다.
수정 시 요구사항
1. groups 적용
인터페이스를 생성하여 저장용 그룹과 수정용 그룹을 구분한다.
2. Item- groups 적용
public class Item {
@NotNull(groups = UpdateCheck.class) //수정시에만 적용
private Long id;
@NotBlank(groups = {SaveCheck.class, UpdateCheck.class})
private String itemName;
3. Controller - @Validated 에 적용할 group을 명시
실제로 많이 사용하는 방식
폼 데이터 전달을 위한 별도의 객체 사용
HTML Form -> ItemSaveForm -> Controller -> Item 생성 -> Repository
폼 데이터 전달을 위한 별도의 객체를 사용하고, 등록, 수정용 폼 객체를 나누면 등록, 수정이 완전히 분리되기 때문에 groups 를 적용할 일은 드물다
@Valid , @Validated 는 HttpMessageConverter ( @RequestBody )에도 적용할 수 있다.
성공
실패 요청 : JSON을 객체로 생성하는 것 자체가 실패함
검증 오류 요청 : JSON을 객체로 생성하는 것은 성공했고, 검증에서 실패함
2번째 - JSON을 객체로 생성하는데 실패를 보면
타입 오류의 경우 HttpMessageConverter 에서 요청 JSON을 ItemSaveForm 객체로 생성하는데 실패한다.
@ModelAttribute 는 필드 단위로 정교하게 바인딩이 적용된다. 특정 필드가 바인딩 되지 않아도 나머지 필드는 정상 바인딩 되고, Validator를 사용한 검증도 적용할 수 있다.@RequestBody 는 HttpMessageConverter 단계에서 JSON 데이터를 객체로 변경하지 못하면 이후 단계 자체가 진행되지 않고 예외가 발생한다. 컨트롤러도 호출되지 않고, Validator도 적용할 수 없다.-스프링에서는 예외 처리의 순서가
컨트롤러(예외발생) -> 인터셉터 -> 서블릿(디스패처 서블릿) -> 필터 -> WAS(톰캣)
의 순으로 된다
WAS까지 해당 예외에 대한 처리가 없으면 기본 오류 화면인 WhiteLabelError와 같은 페이지를 띄운다.
=> 타입에러에 대한 것도 처리를 해줄려면 인터셉터 같은 곳에서 오류 응답을 따로 내보내는 등의 처리를 해줘야 한다. (강의 8,9강)