Validator분리 - @InitBinder, @Validated

2022. 3. 30. 11:19·Languages | Frameworks/Spring

@InitBinder를 사용한 검증

@InitBinder
public void init(WebDataBinder dataBinder) {
    log.info("init binder {}", dataBinder);
    dataBinder.addValidators(itemValidator);
}

이렇게 'WebDataBinder'에 검증기를 추가하면 해당 컨트롤러에서는 검증기를 자동으로 적용할 수 있다.

'@InitBinder' -> 해당 컨트롤러에만 영향을 준다. 글로벌 설정은 별도로 해야함

 

이 후 해당 컨트롤러에서 '@Validated' 어노테이션을 붙여주면 됨

'@Validated'는 검증기를 실행하라는 어노테이션이다.

 

이 어노테이션이 붙으면 앞서 'WebDataBinder'에 등록한 검증기를 찾아서 실행한다. 그런데 여러 검증기를 등록한다면 그 중에 어떤 검증기가 실행되어야 할지 구분이 필요하다. 

 

이때 'supports()'가 사용된다. 여기서는 'supperts(Item.class)'가 호출되고, 결과가 'true'이므로 'ItemValidator'의 'validate()'가 호출된다.

 

 

* 추가로 검증을 하기 위해선 해당 컨트롤러에 ItemValidator 생성자와 ItemValidator 클래스에 검증 내용을 적어놓긴 해야한다

private final ItemValidator itemValidator;

ItemValidator 클래스

//ItemValidator.java

package hello.itemservice.web.validation;

import hello.itemservice.domain.item.Item;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.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[]{1000, resultPrice}, null);
            }
        }
    }
}

 

 

 

글로벌 설정 - 모든 컨트롤러에 다 적용

@SpringBootApplication
public class ItemServiceApplication implements WebMvcConfigurer {

     public static void main(String[] args) {
        SpringApplication.run(ItemServiceApplication.class, args);
    }
    
    @Override
    public Validator getValidator() {
    	return new ItemValidator();
    }
}

이렇게 글로벌 설정을 추가할 수 있다. 기존 컨트롤러의 '@InitBinder'를 제거해도 글로벌 설정으로 정상 동작하는 것을 확인할 수 있다.

 

하지만 글로벌 설정을 하면 BeanValidator가 자동 등록되지 않는데, 글로벌 설정을 직접 사용하는 경우는 드물다.

'Languages | Frameworks > Spring' 카테고리의 다른 글

[SpringBoot] RestApi 구현하기 위한 List<Map> 사용  (0) 2022.05.02
[SpringBoot] mybatis resultType HashMap Null값 받기  (0) 2022.05.02
스프링이 직접 만든 오류 메시지 처리 - 타입 에러처리  (0) 2022.03.21
ValidationUtils  (0) 2022.03.21
MessageCodesResolver - 메세지 우선순위 설정  (0) 2022.03.21
'Languages | Frameworks/Spring' 카테고리의 다른 글
  • [SpringBoot] RestApi 구현하기 위한 List<Map> 사용
  • [SpringBoot] mybatis resultType HashMap Null값 받기
  • 스프링이 직접 만든 오류 메시지 처리 - 타입 에러처리
  • ValidationUtils
Ohde
Ohde
블로그 이사했습니다! https://velog.io/@pigonhair/posts
  • Ohde
    Ohde's Blog
    Ohde
  • 전체
    오늘
    어제
    • 전체 (83)
      • Languages | Frameworks (41)
        • Java (10)
        • Spring (23)
        • Docker (8)
      • Git | Github (1)
      • DBMS (4)
        • SQL (4)
      • DevOps | Server (3)
      • OS (6)
        • Linux (6)
      • Algorithm (26)
        • Theory (1)
        • Data Structure (7)
        • BaekJoon (5)
        • Programmers (1)
        • KBro Study (12)
  • 블로그 메뉴

    • Github
    • BaekJoon
    • solved class
    • 방명록
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Ohde
Validator분리 - @InitBinder, @Validated
상단으로

티스토리툴바