@InitBinder를 사용한 검증
@InitBinder
public void init(WebDataBinder dataBinder) {
log.info("init binder {}", dataBinder);
dataBinder.addValidators(itemValidator);
}
이렇게 'WebDataBinder'에 검증기를 추가하면 해당 컨트롤러에서는 검증기를 자동으로 적용할 수 있다.
'@InitBinder' -> 해당 컨트롤러에만 영향을 준다. 글로벌 설정은 별도로 해야함
이 후 해당 컨트롤러에서 '@Validated' 어노테이션을 붙여주면 됨
'@Validated'는 검증기를 실행하라는 어노테이션이다.
이 어노테이션이 붙으면 앞서 'WebDataBinder'에 등록한 검증기를 찾아서 실행한다. 그런데 여러 검증기를 등록한다면 그 중에 어떤 검증기가 실행되어야 할지 구분이 필요하다.
이때 'supports()'가 사용된다. 여기서는 'supperts(Item.class)'가 호출되고, 결과가 'true'이므로 'ItemValidator'의 'validate()'가 호출된다.
* 추가로 검증을 하기 위해선 해당 컨트롤러에 ItemValidator 생성자와 ItemValidator 클래스에 검증 내용을 적어놓긴 해야한다
private final ItemValidator itemValidator;
ItemValidator 클래스
//ItemValidator.java
package hello.itemservice.web.validation;
import hello.itemservice.domain.item.Item;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@Component
public class ItemValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Item.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
Item item = (Item) target;
if (!StringUtils.hasText(item.getItemName())) {
errors.rejectValue("itemName", "required");
}
if(item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000){
errors.rejectValue("price", "range", new Object[]{1000, 1000000}, null);
}
if(item.getQuantity() == null || item.getQuantity() >= 9999) {
errors.rejectValue("quantity", "max", new Object[]{9999}, null);
}
//특정 필드가 아닌 복합 룰 검증
if (item.getPrice() != null && item.getQuantity() != null) {
int resultPrice = item.getPrice() * item.getQuantity();
if (resultPrice < 10000) {
errors.reject("totalPriceMin", new Object[]{1000, resultPrice}, null);
}
}
}
}
글로벌 설정 - 모든 컨트롤러에 다 적용
@SpringBootApplication
public class ItemServiceApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(ItemServiceApplication.class, args);
}
@Override
public Validator getValidator() {
return new ItemValidator();
}
}
이렇게 글로벌 설정을 추가할 수 있다. 기존 컨트롤러의 '@InitBinder'를 제거해도 글로벌 설정으로 정상 동작하는 것을 확인할 수 있다.
하지만 글로벌 설정을 하면 BeanValidator가 자동 등록되지 않는데, 글로벌 설정을 직접 사용하는 경우는 드물다.
'Languages | Frameworks > Spring' 카테고리의 다른 글
[SpringBoot] RestApi 구현하기 위한 List<Map> 사용 (0) | 2022.05.02 |
---|---|
[SpringBoot] mybatis resultType HashMap Null값 받기 (0) | 2022.05.02 |
스프링이 직접 만든 오류 메시지 처리 - 타입 에러처리 (0) | 2022.03.21 |
ValidationUtils (0) | 2022.03.21 |
MessageCodesResolver - 메세지 우선순위 설정 (0) | 2022.03.21 |