Validator 인터페이스를 상속받아 사용
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 result = item.getPrice() * item.getQuantity();
if (result < 10000) errors.reject("totalPriceMin",new Object[]{10000,result},null);
}
}
}
public String addItemV5(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
if (itemValidator.supports(item.getClass())) {
itemValidator.validate(item, bindingResult);
}
//검증에 실패하면 다시 입력 폼으로
if (bindingResult.hasErrors()) {
log.info("error = {}", bindingResult);
return "validation/v2/addForm";
}
//성공 로직
Item savedItem = itemRepository.save(item);
redirectAttributes.addAttribute("itemId", savedItem.getId());
redirectAttributes.addAttribute("status", true);
return "redirect:/validation/v2/items/{itemId}";
}
검증기를 사용해서 검증로직을 컨트롤러와 분리할 수 있다.
다음 코드를 특정 컨트롤러에 추가하고 파라미터에 @Validated @ModelAttribute Item item
와 같이 @Validated를 설정한다면 매 요청시마다 자동으로 검증로직을 수행하게 된다.
@InitBinder
public void init(WebDataBinder dataBinder) {
dataBinder.addValidators(itemValidator);
}
만약 WebDataBinder에 추가된 검증기가 여러가지라면 검증기의 surports() 메서드가 어떤 검증기가 실행되어야 하는지 활용된다.
모든 컨트롤러에서 동일한 검증자격이 필요할 때 다음과 같이 WebMvcConfigurer를 상속받아 getValidator()를 재구현해 공통 검증기를 추가할 수 있다.
@SpringBootApplication
public class ItemServiceApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(ItemServiceApplication.class, args);
}
@Override
public Validator getValidator() {
return new ItemValidator();
}
}
@Valiated 는 스프링 전용 검증 어노테이션
@Valid 는 자바 표준 검증 어노테이션