[Spring] Validation이란?

2020년 01월 13일 by Xion

    [Spring] Validation이란? 목차

Validation 이란?

-애플리케이션에서 사용하는 객체들을 검증할 때 사용하는 interface.

-실제 검증보단 간단한 검증을 위한 @(어노테이션)을 사용하고 @으로 검증할 수 없는 복잡한 검증 과정이 필요한 경우, 사용자가 검증을 커스텀하기 위해 구현한다.

 

Event

public class Event {
    Integer num;
    // null 이면 안됨
    String title;
​
    public Integer getNum() {
        return num;
    }
​
    public void setNum(Integer num) {
        this.num = num;
    }
​
    public String getTitle() {
        return title;
    }
​
    public void setTitle(String title) {
        this.title = title;
    }
}


검증할 (사용자의 요청값) 대상인 Event Class입니다. 간단히 title은 null이 되면 안된다는 조건을 걸었다고 가정하겠습니다. 중요하면서 당연한 점은 getter가 있어야 validator에서 해당 값을 가져다 사용할 수 있다는 점입니다.

 

EventValidator

 

public class EventValidator implements Validator {
​
    @Override
    public boolean supports(Class<?> clazz) {
        return Event.class.equals(clazz);
    }
​
    @Override
    public void validate(Object target, Errors errors) {
        Event event = (Event)target;
​
        if(isEmptyOrWhitespace(event.getTitle())){
            errors.rejectValue("title", "empty");
        }
​
    }
​
    public boolean isEmptyOrWhitespace(String value){
        if (value == null || value.trim().length() == 0)
            return true;
        return false;
    }
}

Event 객체를 검증하기 위한 Validator 입니다. Validator Interface를 구현하며 구현해야할 메소드는 2가지 입니다.

 

supports()

- supports는 주어진 객체가 지원이 가능한지를 파악하는 메소드입니다. 위의 supports()에서는 Event class가 Validator가 지원하는 객체인지를 파악하기 위해 return Event.class.equals(clazz)를 기술했습니다.

 

validate()

- validate()를 호출하면 첫번째 매개변수로 전달받은 target 객체에 대한 유효성을 검증하고, 2번 째 매개변수인 errors에 target객체에 대한 에러들을 담게됩니다.

- 자세히 설명드리겠습니다. validate에서는 우선 첫번째로 전달되는 검증 대상 객체(target)을 해당 Class Type으로 형변환을 했습니다. 그후 값 검증을 위해 원하는 값임을 검증하는 메소드인 isEmptyOrwhitespace(String value)를 만들었습니다. 간단히 설명드리면 매개변수로 전달받는 value가 null인지 그리고 공백을 제거한 길이가 0인지를 검사하는 메소드입니다.

 

다시 validate()메소드 에서는 isEmptyOrWhitespace() 메소드를 이용해 값이 유효한지 검사를 하고 유효하지 않을 시 두번째 매개변수로 전달받는 errors객체의 rejectValue()메소드를 호출 했습니다. errors객체에는 validate()를 통해 검증에 실패한 값을 전달하고 이에 따른 message를 맵핑 시킬 수 있습니다. 이전 시간에 살펴보았던 IoC 컨테이너의 MessageSource 기능을 살펴보면 될 것 같습니다.

조금 더 자세히 설명 드리면 errors.rejectValue()는 첫번째 매개변수로 값 검증에 실패한 객체의 filed(변수)를 전달하고 이 실패에 대한 message를 개발자가 작성한 message.properties에서 찾기위한 key 값을 2번째 매개변수로 전달하는 것 입니다.

 

ValidationUtils

사실 위와 같이 간단한 검증의 경우에는 Springframework에서 제공하는 라이브러리를 이용해 검증할 수도 있습니다. 바로 ValidationUtils의 메소드들을 사용하면 됩니다. 바로 예시를 보겠습니다.

 

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", "empty", "title 가 empty");
    }
}

간단해진 코드를 볼 수있습니다. target 객체의 특정 필드값을 검증하기 위해 간단히 rejectIfEmptyOrwhitespace()메소드를 사용한것을 볼 수 있습니다. 1번째 매개변수로는 검증의 결과로 발생된 error들을 담기 위한 errors 객체를 넘겨주고, 두번째 매개변수에는 검증을 원하는 target 객체의 filed, 3번째 매개변수로는 MessageSource의 message key값 , 마지막으로 key에 해당하는 message가 존재하지 않는 경우의 default Message를 넣어주면 됩니다.

 

즉, ValidationUtils.rejectIfEmptyOrWhitespace(errors,"객체의filed값","messaget의 key값","default Message값")

 

 

검증 Annotation

이번엔 어노테이션을 이용한 객체의 값 검증방법을 알아보도록 하겠습니다.

 

Event

public class Event {
    @Min(0)
    Integer id; // 0 이상이어야 함.
    @NotNull @NotBlank
    String title; // null 이면 안됨, 공백제외 문자열 0이상
    @Email
    String email; // 이메일의 형식이어야 함.
​
    //getter , setter
}

검증을 위한 event Class입니다. 검증 대상은 각각 num, title, email입니다.
1. num

- 수가 0보다 같거나 커야합니다.

- @Min(0) 어노테이션을 이용해 검증절차를 기술했습니다.

2. title

- title이 null이면 안되며, 공백을 제외한 길이가 0보다 커야합니다.

- @NotNull 을 이용해 null이 안되는 조건을 표기하였고, @NotBlank 를 이용해 공백을 제외한 길이가 0보다 커야함을 표기했습니다.

3. email

- email 형식을 띄어야 합니다.

- @Email 을 이용해 이메일 형식을 띄어야하는 조건을 표기했습니다.

 

이 밖에도

문자열 길이를 검증하는 @Size 등의 다양한 검증 annotation이 있습니다.

아래 링크를 참고

http://hibernate.org/validator/

 

 

 

Runner

 

@Component
public class AppRunner implements ApplicationRunner {
​
    @Autowired
    @Qualifier("defaultValidator")
    Validator validator;
​
    @Override
    public void run(ApplicationArguments args) throws Exception {
        Event event = new Event();
        event.setId(-1);
        event.setTitle("");
        event.setEmail("aaasda");
​
        // error 검증
        Errors errors = new BeanPropertyBindingResult(event, "event");
        validator.validate(event, errors);
​
        // error 들을 출력함
        System.out.println(errors.hasErrors());
        errors.getAllErrors().forEach(e -> {
            System.out.println("=========== ERROR ============");
            Arrays.stream(e.getCodes()).forEach(System.out::println);
            System.out.println(e.getDefaultMessage());
        });
    }
}
​
== 결과 ==
true
=========== ERROR ============
Email.event.email
Email.email
Email.java.lang.String
Email
이메일 주소가 유효하지 않습니다.
=========== ERROR ============
NotBlank.event.title
NotBlank.title
NotBlank.java.lang.String
NotBlank
반드시 값이 존재하고 공백 문자를 제외한 길이가 0보다 커야 합니다.
=========== ERROR ============
Min.event.id
Min.id
Min.java.lang.Integer
Min
반드시 0보다 같거나 커야 합니다.

검증 조건을 만들었으니 이번엔 검증을 해봐야겠죠? 검증을 위한 Validator 객체를 @Autowired로 주입받습니다. 이때 하위 객체들이 많으므로 @Qualifier를 이용해 defaultValidator가 주입되도록 했습니다.

 

실행문을 보면 검증 target인 Event 객체를 생성하고, 검증조건에 어긋나는 값들을 set하였습니다. 그 후 Errors 객체를 생성하고 Validator의 validate 메소드에 target과 errors를 매개변수로 전달하여 호출 했습니다.

 

이렇게 되면 errors 객체에 검증의 결과로 발생한 error들이 담기게 되어 error들을 출력할 수 있습니다.

 

 

더보기



출처: https://galid1.tistory.com/518?category=769011 [배움이 즐거운 개발자]

'Spring' 카테고리의 다른 글

[Spring]Resource 추상화  (0) 2020.01.14
[Spring] DataBinding추상화,Converter,Formatter란?  (0) 2020.01.14
[Spring] ApplicationEventPublisher란?  (0) 2020.01.13
[Spring] Environment 프로파일이란?  (0) 2020.01.13
[Spring] Bean의 Scope  (0) 2020.01.13