모르지 않다는 것은 아는것과 다르다.

Spring

커스텀 Validator 구현

채마스 2022. 2. 26. 09:51

커스텀 Validator 구현

 

개요

  • 보통 나는 필드는 @Valid 를 사용해서 validation 을 처리했고, 메소드의 파라미터는 @Validated 를 통해서 진행했다.
  • 하지만 메소드 내에서 validation 을 처리하고 싶었다. 그렇기 때문에 메소드 내에서도 validation 을 할 수 있게 커스텀 Validator 를 구현해볼 생각이다.





방법1. Spring Validator 인터페이스 구현하기

  • 스프링 프레임워크 4.0은 빈 검증기 1.0(JSR-303) 와 1.1(JSR-349)를 지원하며 Spring의 Validator 인터페이스에 적용할 수 있다.
package org.springframework.validation;

public interface Validator {
    boolean supports(Class<?> var1);

    void validate(Object var1, Errors var2);
}
  • Validator 인터페이스는 두가지 메서드를 정의하는데, supports메서드와 validate메서드이다.
    • supports 메소드는 검증하고자 하는 객체가 validator에서 지원하는지 아닌지 확인하는 메소드다.
    • validate 메소드는 실제 로직을 구현하는 메소드이다.
public class CustomValidator implements Validator {
    @Override
    public boolean supports(Class<?> aClass) {
        return UserDto.class.equals(aClass);
    }

    @Override
    public void validate(Object target, Errors errors) {

        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userId", "NOT_EMPTY", "DEFALT_MESSAGE");

        //이 위치에 추가로 로직을 넣을 수 있다. 

    }
}
  • supports 메소드는 해당 객체가 validator 가 지원하는 객체인지 판단한다.
  • rejectIfEmptyOrWhitespace 함수의 경우 해당 필드가 비어있거나 공백일 경우 발생시킨다.
  • 1번인자 Error객체, 2번인자 필드이름, 3번인자 에러코드, 4번인자 디폴트 메세지다.
  • 위의 경우 만약 userId 가 null 이면 에러코드를 뱉는다.
  • 위에서 구현한 CustomValidator 는 아래와 같이 사용될 수 있다.
public void searchUser(UserDto userDto){
    CustomValidator validator = new CustomValidator();
    Errors errors = new BeanPropertyBindingResult(userDto, "userDto");
    validator.validate(userDto, errors);
    System.out.println(errors.hasErrors());
    // ... 생략
}
  • Errors는 인터페이스이고 이를 구현한 구현체는 BeanPropertyBindingResult 인데, 파라미터로 검증할 객체와 객체의 이름을 String으로 넘긴다.






방법2. Validator 를 주입받은 CustomValidator 컴포넌트 구현

  • 아래와 같이 Validator 를 주입 받아서 Validator 를 구현할 수 있다.
@Component
@RequiredArgsConstructor
public class CustomValidator {

    private final Validator validator;

    public void validate(Object object) {

        if (object == null) return;

        BindingResult errors = new BeanPropertyBindingResult(object, object.toString());
        validator.validate(object, errors);
        if (errors.hasErrors()) throw new CustomException(errors);
    }

    public void validateList(List<?> list) {

        if (list == null || list.isEmpty()) return;

        BindingResult errors = null;
        for (Object object : list) {
            if (errors == null){
                errors = new BeanPropertyBindingResult(object, object.toString());
            }
            validator.validate(object, errors);   
        }
        if (errors.hasErrors()) throw new CustomException(errors);
    }
}
  • dto 를 validation 처리하는 validate 메소드와 dto 리스트를 validation 처리하는 validateList 메소드를 구현했다.
  • BeanPropertyBindingResult 를 통해서 dto 를 검증하고, 주입받은 Validator 의 validator 메소드를 실행시킨다.
  • 위에서 구현한 내용은 아래와 같이 사용될 수 있다.
    private final CustomValidator validator;

    public void searchUser(UserDto dto, List<UserDto> dtoList){
        validator.validate(dto);
        // ... 생략
        validator.validateList(dtoList);
        // ... 생략
    }
  • 위와 같이 dto 와 dto 리스트로 담겨져 들어오는 파라미터를 validation 할 수 있다.




REFERENCES

'Spring' 카테고리의 다른 글

쿠키와 세션을 사용한 로그인 처리  (0) 2022.02.26
컴포넌트스캔  (0) 2022.02.26
의존관계 주입  (0) 2022.02.26
싱글톤 컨테이너  (0) 2022.02.26
스프링 타입 컨버터  (0) 2022.02.26