[Spring] Validator가 여러 개 일때 통합 Validator 만들기
반응형

Validator 인터페이스를 구현하는 식으로 Validation을 해주려고 한다.

 

스프링에서는 Validator 인터페이스를 지원하여 어플리케이션에서 사용하는 객체를 검증할 수 있는 기능을 제공한다. 

 

validation 이란 유효성을 검증하는 것으로

 

 

 

예를 들면

 

          회원가입을 할 때 아이디가 너무 짧으면 몇 글자 이상으로 만들어야 한다고 알려준다거나

 

          중복되는 아이디가 있으면 이미 사용되고 있는 아이디라고 알려준다거나 

 

 

 

 

데이터가 정해진 기준을 충족하는지 검사를 하는 기능이라고 보면 된다.

 

 

 

 

시행하는 서비스 별로 Validator를 구분해서 만드려고 하는데 Validator가 많아질 수록 한눈에 보기도 불편하고

 

컨트롤러마다 이름을 수정을 해줘야하는 것이 번거로웠다.

 

한 Validator 안에 서비스 구분없이 넣자니 너무 보기가 더러웠다.

 

그래서 어떤 Validator가 있는지 한 클래스 안에서 다 볼 수 있는 통합 Validator가 있었으면 좋겠다고 생각했다.

 

그렇게 Generic Validator라는 것을 만들게 되었다.

 

 

 

인간과 동물의 정보를 유효성을 검증하고 싶은 예로 만들어 보았다.

(인간Validator와 동물Validator는 따로 만들어 놓은 것을 전제로 한다.)

public class GenericValidator implements Validator {
	
		private HumanService humanService;
		private AnimalService animalService;
	
		public GenericValidator(HumanService humanSerivce, AnimalService animalService) {
			this.humanService = humanSerivce;
			this.animalService = animalService;
		}
		
	

		@Override
		public boolean supports(Class<?> clazz) {
			return HumanDTO.class.isAssignableFrom(clazz) 
					|| AnimalDTO.class.isAssignableFrom(clazz)
					;
		}
		
        
        
		@Override
		public void validate(Object target, Errors errors) {
			
		     if (target instanceof HumanDTO) {
	             ValidationUtils.invokeValidator(new HumanValidator(humanService), target, errors);
	         }
	         if (target instanceof AnimalDTO) {
	             ValidationUtils.invokeValidator(new AnimalValidator(animalService), target, errors);
	         }
		}
}

 

하나하나 따로 떼서 보자

 

public class GenericValidator implements Validator {
	
		private HumanService humanService;
		private AnimalService animalService;
	
		public GenericValidator(HumanService humanSerivce, AnimalService animalService) {
			this.humanService = humanSerivce;
			this.animalService = animalService;
		}

기본 생성자를 만들어준다.

 

		@Override
		public boolean supports(Class<?> clazz) {//clazz라고 쓰는 이유는 class는 이미 있는 예약어라서 그렇다고 한다.
			return HumanDTO.class.isAssignableFrom(clazz) || AnimalDTO.class.isAssignableFrom(clazz);
	//검증할 클래스가 사람데이터라면 바로 리턴, 아니라면 동물데이터로 넘어감.
	//검증할 클래스를 두개 이상으로 더 추가해도 된다.
		}

 

검증할 내용

     
		@Override
		public void validate(Object target, Errors errors) {
			
		     if (target instanceof HumanDTO) {	//만약 검증할 데이터가 사람 데이터라면..
	             ValidationUtils.invokeValidator(new HumanValidator(humanService), target, errors);
	         }
	         if (target instanceof AnimalDTO) {	//만약 검증할 데이터가 동물 데이터라면...
	             ValidationUtils.invokeValidator(new AnimalValidator(animalService), target, errors);
	         }
		}
}

객체타입을 확인하는 instanceof 연산자를 사용해서 어떤 DTO가 들어왔는지 확인해준다.

 

(instanceof는    객체 instanceof 클래스    로 선언해서 사용한다. 참/거짓이 반환된다.)

 

그리고 객체타입이 맞다면

 

invokeValidator(Validator, 객체, 에러) 를 넣어 실행할 Validator를 정하고, 객체를 정하고, 에러를 담는다.

 

 

반응형