Spring

검증1 - Validation : Validator 분리1,2

sami355 2022. 8. 26. 01:18

인프런 김영한님의 스프링mvc2편을 보고 정리한 글입니다.

무엇을 배웠나요?

Validator 분리1

  • 스프링은 검증을 체계적으로 제공하기 위해 다음 인터페이스를 제공한다.
  • public interface Validator { boolean supports(Class<?> clazz); void validate(Object target, Errors errors); }
  • supprort(){} : 해당 검증기를 지원하는 여부 확인
  • validate(Object target, Errors errors) : 검증 대상 객체와 BindingResult

Validator 분리2

  • WebDataBinder는 스프링의 파라미터 바인딩의 역할을 해주고 검증 기능도 내부에 포함한다.
  • @InitBinder public void init(WebDataBinder dataBinder) { log.info("init binder {}", dataBinder); dataBinder.addValidators(itemValidator); }
  • WebDataBinder 에 검증기를 추가하면 해당 컨트롤러에서는 검증기를 자동으로 적용할 수 있다.
  • @InitBinder 해당 컨트롤러에만 영향을 준다. 글로벌 설정은 별도로 해야한다. but 실제로는 글로벌로 검증기를 잘 사용하지는 않는다.
  • @IninBinder를 사용하려면 @Validated를 추가해줘야 한다.
  • @Validated 동작방식은 다음과 같다.이 애노테이션이 붙으면 앞서 WebDataBinder 에 등록한 검증기를 찾아서 실행한다.여기서는 supports(Item.class) 호출되고, 결과가 true 이므로 ItemValidator 의 validate()가 호출된다.
  • 만약 여러 검증기를 등록한다면 그 중에 어떤 검증기가 실행되어야 할지 구분이 필요하다. 이때 supports() 가 사용된다.
  • @Validated 는 검증기를 실행하라는 애노테이션이다

궁금한 점은 무엇인가요?

  • Validator의 Support에서 class.isAssignableFrom() 는 무슨 역할을 하는가
  • 특정 클래스가 뒤에 나오는 클래스를 상속했거나 구현했는지 확인해서 true 혹은 false를 반환하는 메서드
  • WebDataBinder는 스프링의 파라미터 바인딩의 역할을 해주고 검증 기능도 내부에 포함한다고 나와 있는데 그러면 WebDataBinder에도 파라미터가 바인딩 되고 model에도 파라미터가 바인딩이 되는것인가??

더 필요하다고 생각한 것이 있나요?

코드

@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");
 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() > 10000) {
 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);
 }
 }
 }
}