Controller와 Validation 분리

wangjh789·2022년 8월 8일
0

[Spring] 스프링-mvc-2

목록 보기
3/11

Validator

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}";
    }

검증기를 사용해서 검증로직을 컨트롤러와 분리할 수 있다.

WebDataBinder

다음 코드를 특정 컨트롤러에 추가하고 파라미터에 @Validated @ModelAttribute Item item와 같이 @Validated를 설정한다면 매 요청시마다 자동으로 검증로직을 수행하게 된다.

	@InitBinder
    public void init(WebDataBinder dataBinder) {
        dataBinder.addValidators(itemValidator);
    }

만약 WebDataBinder에 추가된 검증기가 여러가지라면 검증기의 surports() 메서드가 어떤 검증기가 실행되어야 하는지 활용된다.

Global 설정

모든 컨트롤러에서 동일한 검증자격이 필요할 때 다음과 같이 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();
	}
}

@Validated, @Valid 차이

@Valiated 는 스프링 전용 검증 어노테이션
@Valid 는 자바 표준 검증 어노테이션

profile
기록

0개의 댓글