검증 로직을 공통화하고 표준화 한 것
Bean Validation은 특정한 구현체가 아니라 자바 기술 표준이다. 즉 검증 어노테이션과 여러 인터페이스의 모음이다.
ex) JPA = 표준 기술, Hibernate = 구현체
Bean Validation을 구현한 기술 중에서 일반적으로 사용하는 구현체는 Hibernate Validator다.
Bean Validation을 사용하려면 build.gradle에 의존성을 추가해야 한다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
이렇게 의존성을 추가하게 되면 jakarta.validation 인터페이스가 생기고 Hibernate Validator 구현체가 jakarta.validation 인터페이스를 동작한다.
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@NotBlank
private String itemName;
@NotNull
@Range(min= 1000, max= 1000000)
private Integer price;
위의 코드를 보면 @NotBlank, @NotNull, @Range 모두 Bean Validation이지만 import된 클래스의 패캐지 명이 다른 걸 볼 수 있는데
@NotBlank, @NotNull은 Java Validation으로 시작하는 어노테이션으로 Bean Validation에서 표준으로 제공하기 때문에 어떤 구현체에서도 사용가능하지만 @Range는 Hibernate Validator 구현체에서만 동작한다.
cf) 대부분 Hibernate Validator를 사용하므로 자유롭게 사용해도 상관없다.
@NotBlank : null , ""(공백)을 허용하지 않는다.
@NotNull : null을 허용하지 않는다.
--> @NotBlank가 @NotNull보다 좀 더 엄격한 검증 조건이다.
스프링부트는 아래의 라이브러리를 넣으면 자동으로 Bean Validator을 인지하고 스프링에 통합한다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
스프링부트는 위의 라이브러리를 등록하면 'LocalValidatorFactoryBean'을 글로벌 Validator로 등록하는데
이 Validator는 @NotNull 같은 어노테이션을 보고 검증을 수행한다.
이렇게 글로벌 Validator가 적용되어 있기 때문에 @Valid, @Validated만 적용하면 된다.
또한 검증 오류가 발생하면 'FieldError' 'ObjectError'를 생성해서 BindingResult에 담아준다.
cf) @Valid, @Validated 없으면 검증 수행 안함
@SpringBootApplication
public class ItemServiceApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(ItemServiceApplication.class, args);
}
@Override
public Validator getValidator(){
return new ItemValidator();
}
}
위의 코드와 같이 글로벌 Validator를 직접 등록하면 스프링부트는 Bean Validator를 글로벌 Validator로 등록하지 않는다.
따라서 어노테이션 기반의 빈 검증기가 동작하지 않는다.
만약 binding 실패 --> typeMissmatchException으로 'FieldError' 추가
Binding에 성공한 필드만 Bean Validation에 적용한다.
BeanValidator는 Binding에 실패한 필드는 Bean Validation에 적용하지 않는다.
출처 : 스프링 MVC 2편 : 백엔드 웹 개발 활용 기술