Free Lines Arrow
본문 바로가기
Spring/spring mvc 2 스터디

[Spring] Validation: Validator

by skahn1215 2022. 2. 2.
728x90
반응형

Validator

  • 지금까지 검증로직을 구현해 왔다.
  • 하지만 컨트롤러에 검증로직이 차지하는 비중이 너무 크다.
  • Validator 역할을 분리하여 사용하자

 

ItemValidator 구현

Validator Interface

  • 스프링은 검증을 제공하기 위해 인터페이스를 제공한다.
public interface Validator {
    boolean supports(Class<?> clazz);
    void validate(Object target, Errors errors);
}

 

구현

  • supports(){}:
     - 해당 검증기를 지원하는 여부
  • validate(Objectm target, Errors errors);
     - 검증 대상 객체와 BindResult
@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;
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "itemName",
            "required");
    }
}

 

컨트롤러에서 호출

private final ItemValidator itemValidator;
@PostMapping("/add")
public String addItemV5(@ModelAttribute Item item, BindingResult bindingResult,
RedirectAttributes redirectAttributes) {

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

 

Validator 개선

  • Validator 인터페이스를 별도로 제공하는 이유는 체계적으로 검증 기능을 도입하기 위함이다.
  • 인터페이스를 사용해서 구현을 하게 되면 스프링의 도움을 받을수 있다.

 

WebDataBinder 사용

  • 파라미터 바인딩의 역할을 해주고 검증 기능도 내부에 포함한다.
  • 컨트롤러에 아래 코드를 넣어준다.
  • WebDataBinder를 추가하면 검증기가 자동으로 적용된다.
    - 단 검증을 위한 파라미터에 @Validated를 사용해야된다.
    @InitBinder
    public void init(WebDataBinder dataBinder) {
        log.info("init binder {}", dataBinder);
        dataBinder.addValidators(itemValidator);
    }​

@Validated 적용

  • 직접 Validator를 호출하지 않고 @Validated를 추가해주었다.
@PostMapping("/add")
public String addItemV6(@Validated @ModelAttribute Item item, BindingResult
bindingResult, RedirectAttributes redirectAttributes) {
    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}";
}

 

동작방식

  • @Validated 를 붙이게 되면 WebDataBinder 에 등록한 검증기를 찾아서 실행한다.
  • 그런데 여러 검증기를 등록한다면 그 중에 어떤 검증기가 실행되어야 할지 구분이 필요하다.
  • 이때 supports() 가 사용된다

 

728x90
반응형

댓글