Validator
public interface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errors errors);
}
- Spring이 체계적으로 검증 기능을 도입하기 위해 해당 인터페이스 제공
- supports() : 해당 검증기를 지원하는 여부 확인
- validate(Object target, Errors errors) : 검증 대상 객체와 BindingResult를 넘겨서 검증을 수행하고 오류가 있으면 담음
- Errors는 BindingResult의 상위 인터페이스
1. 직접 호출
- 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[]{10000,resultPrice},null);
}
}
}
}
- Controller
public class ValidationItemControllerV2 {
private final ItemRepository itemRepository;
private final ItemValidator itemValidator;
@PostMapping("/add")
public String addItemV5(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
itemValidator.validate(item, bindingResult); // 직접 호출
// 검증에 실패하면 다시 입력 폼으로
if(bindingResult.hasErrors()){
log.info("errors = {}", 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}";
}
}
2. WebDataBinder를 통해서 사용
- Controller
- @Validated : 검증기를 실행하라는 애노테이션
- 해당 애노테이션이 붙으면 WebDataBinder에 등록한 검증기를 찾아서 실행
- 여러 검증기 등록 시 supports()를 통해 어떤 검증기가 실행되어야 하는지 구분
public class ValidationItemControllerV2 {
private final ItemRepository itemRepository;
private final ItemValidator itemValidator;
@InitBinder
public void init(WebDataBinder dataBinder){
// WebDataBinder에 검증기를 추가하면 해당 컨트롤러에서는 검증기가 자동으로 적용
dataBinder.addValidators(itemValidator);
}
@PostMapping("/add")
public String addItemV6(@Validated @ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
// itemValidator.validate(item, bindingResult);
// 검증에 실패하면 다시 입력 폼으로
if(bindingResult.hasErrors()){
log.info("errors = {}", 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}";
}
}
'Java > Spring MVC' 카테고리의 다른 글
서블릿 필터 (0) | 2024.07.11 |
---|---|
Bean Validation (0) | 2024.06.29 |
BindingResult (0) | 2024.06.27 |
Model과 @ModelAttribute (0) | 2024.06.08 |
@Controller와 @RestController (1) | 2024.06.06 |