[Spring] Validation 추상화

2022. 10. 28. 18:39JAVA/Spring

1. Validation 추상화

애플리케이션에서 사용하는 객체 검증용 인터페이스입니다

Validation 추상화의 특징

  • 자바 EE 스펙중 하나입니다.
  • 어떠한 계층과도 관계없이 모든 계층(웹, 서비스, 데이터)에서 사용해도 좋다
  • 구현체 중 하나로, JSR-303(Bean Validation 1.0)과 JSR-349(Bean Validation 1.1)을 지원합니다. (LocalValidatorFactoryBean)
  • DataBinder에 들어가 바인딩 할 때 같이 사용되기도 한다

Validator 인터페이스

  • boolean supports(Class clazz) : 어떤 타입의 객체를 검증할때 사용할 것인지 결정함
  • void validate(Object obj, Errors e) : 실제 검증 로직을 이 안에서 구현
    • 구현할 때 ValidationUtils 사용하며 편리함

스프링 부트 2.0.5 이상 버전을 사용할 때

  • LocalValidatorFactoryBean 빈으로 자동 등록
  • JSR-380(Bean Validation 2.0.1) 구현체로 hibernate-validator 사용.
  • https://beanvalidation.org/

 

2. Validator 인터페이스 구현 실습

1. 필드멤버에 바인딩 시킬 클래스 정의

@Getter
@Setter
public class Event {
    Integer id;

    @NotEmpty
    String  title;

    @Min(0)
    @NotNull
    Integer limit;

    @Email
    String email;

}

 

  • @NotEmpty : 문자열 값이 null이거나 비어있는지 검증하는 애노테이션
  • @Min(0) : 정수값이 최소 0보다 같거나 큰지 검증하는 애노테이션
  • @NotNull : 값이 Null이 아닌지 검증하는 애노테이션
  • @Email : 문자열 값이 이메일 형식인지 검증하는 애노테이션

 

2. 바인딩 시킬 클래스를 검증하는 Validation 구현 클래스 정의

public class EventValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return Event.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors,
                                            "title",
                                        "notempty",
                                    "Empty title is not allowed");

        // errors 인스턴스에 직접 에러 작성
        Event event = (Event) target;
        if(event.getTitle() == null){
            errors.reject("notempty", "Empty title is not allowed");
            errors.rejectValue("title", "notempty", "Empty title is not allowed");
        }

    }
}
  • supports() 메서드 : 검증해야 하는 인스턴스의 클래스 타입이 Validator가 지원하는 타입인지 검사하는 메서드입니다.
    • 파라미터로 전달된 클래스 타입이 Event 타입인지 검사합니다.
  • validate() 메서드 : 필드 멤버에 바인딩 시킬 값이 적절한지 검증하는 메서드입니다.
    • ValidationUtils.rejectIfEmptyOrWhitespace(Errors, field, errorCode, defaultMessage) : 필드와 에러 코드, 에러가 발생할시 메시지를 정의합니다. defaultMessage는 에러 코드로 메시지를 찾지 못했을때 기본값 메시지입니다.
    • ValidationUtils 유틸리티 클래스를 사용하지 않는대신 직접 Errors 인스턴스에 에러를 작성할 수 있습니다.

 

3. 클라이언트 코드를 작성합니다.

@Component
@AllArgsConstructor
public class AppRunner implements ApplicationRunner {
    private final Validator validator;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Event event = new Event();
        EventValidator eventValidator = new EventValidator();
        Errors errors = new BeanPropertyBindingResult(event, "event");

        eventValidator.validate(event, errors);
        System.out.println(errors.hasErrors());
        printErrors(errors);
		}
}

실행결과는 다음과 같습니다.

true
========Error Code=======
notempty.event.title
notempty.title
notempty.java.lang.String
notempty
Empty title is not allowed

실행결과를 보면 Event 인스턴스의 title 멤버에 값을 설정하지 않았기 때문에 에러가 있다는 것을 알 수 있고 Error Code를 보면 notempty 외의 3개의 에러 코드가 더 있습니다. 이것은 Validator에서 알아서 추가한 것입니다.

 

 

References

source code : https://github.com/yonghwankim-dev/spring_study/tree/master/spring_validation/src/main/java/kr/yh
[인프런] 스프링 프레임워크 핵심 기술