Bean Validation이란?
- 특정한 구현체가 아니라 Bean Validation 2.0(JSR-380)이라는 기술 표준이다.
- 검증 애노테이션과 여러 인터페이스의 모음이다.
- JPA가 기술 표준이고 그 구현체로 하이버네이트가 있는 것과 같다.
- Bean Validation을 구현한 기술중에 일반적으로 사용하는 구현체는 하이버네이트 Validator이다.
Bean Validation 의존성
- Jakarta Bean Validation
- jakarta.validation-api : Bean Validation 인터페이스
- hibernate-validator 구현체
Bean Validation 사용해보기
- javax.validation.constraints.NotNull
- org.hibernate.validator.consraints.Range
- javax.validation으로 시작하면 특정 구현에 관계없이 제공되는 표준 인터페이스이다.
- 하이버네이트로 시작하면 하이버네이트 validator 구현체를 사용할 때만 제공되는 검증 기능이다.
스프링 MVC는 어떻게 Bean Validator를 사용할까?
- 스프링 부트가 spring-boot-stater-validation 라이브러리를 넣으면 자동으로 Bean Validator를 인지하고 스프링에 통합한다.
- 스프링 부트는 자동으로 글로벌 Validator를 등록한다.
- LocalValidatorFactoryBean을 글로벌 Validator로 등록한다.
- 이 Validator는 NotNull과 같은 애노테이션을 보고 검증을 수행한다.
- 이렇게 글로벌 Validator가 적용되어 있지 않기 때문에 Valid, Valiated애노테이션만 적용하면 된다.
검증이 일어나는 순서
- ModelAttribute 각각의 필드에 타입변환을 시도한다.
- 성공하면 다음으로
- 실패하면 typeMismatch로 FieldError로 추가한다.
- Validator를 적용한다.
- 바인딩에 성공한 필드만 Bean Validation을 적용한다.
- 바인딩에 실패한 필드는 적용하지 않는다.
- 생각해보면 타입변환에 성공해서 바인딩부터 성공을 해야 Validation 적용의 의미가 생긴다.
- 일단 모델 객체에 바인딩 받는 값이 정상으로 들어와야 검증도 의미가 생긴다.
- 예시)
- ItemName에 문자 A 입력 > 타입변환 성공 > Validator 적용 > price 에 문자 “A”입력 > 타입변환 실패 > 타입 미스매치 필드에러 추가 > price는 Validator 적용 X
- NotBlank라는 오류코드를 기반으로 MessageCodesResolver를 통해 다양한 메시지 코드가 순서대로 생성된다.
BeanValidation 메시지 찾는 순서는 어떻게 될까?
- 생성된 메시지 코드 순서대로 messageSource에서 메시지를 찾는다.
- 애노테이션의 message 속성을 사용 → NotBlank(message = “공백! {0}”)
- 라이브러리가 제공하는 기본 값 사용 → 공백일 수 없습니다.
필드말고 오브젝트에 대한 오류는 어떻게 처리할까?
- @ScriptAssert()를 사용한다.
- 메시지코드
- ScriptAssert.item
- ScriptAssert
- 하지만 위의 방법은 제약이 많고 복잡하다는 단점이 존재한다. 또한 실무에서 검증 기능이 해당 객체의 범위를 넘어서는 경우도 종종 발생하는데 그런 경우 대응이 어렵다.
- 따라서 오브젝트 오류는 직접 자바 코드로 작성하는것을 권장한다.