Validation에 대해서 알아보도록 하겠습니다.
1. Validation 이란?
어플리케이션에서 사용하는 객체들을 검증할 때 사용하는 인터페이스 입니다! 실제로는 직접 구현하여 사용하는 경우보다는 간단히 검증을 위한 @을 사용하고, @으로 검증을 할 수 없는 복잡한 검증 과정이 필요한 경우에 사용자가 검증을 커스텀하기 위해 구현합니다. 바로 예제를 보겠습니다.
1. Event
xpublic 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에서 해당 값을 가져다 사용할 수 있다는 점입니다.
2. EventValidator
xxxxxxxxxx
public class EventValidator implements Validator {
public boolean supports(Class<?> clazz) {
return Event.class.equals(clazz);
}
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
의 메소드들을 사용하면 됩니다. 바로 예시를 보겠습니다.
xxxxxxxxxx
public class EventValidator implements Validator {
public boolean supports(Class<?> clazz) {
return Event.class.equals(clazz);
}
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를 넣어주면 됩니다.
2. 검증 Annotation
이번엔 어노테이션을 이용한 객체의 값 검증방법을 알아보도록 하겠습니다.
Event
xxxxxxxxxx
public class Event {
0) (
Integer id; // 0 이상이어야 함.
String title; // null 이면 안됨, 공백제외 문자열 0이상
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
xxxxxxxxxx
public class AppRunner implements ApplicationRunner {
"defaultValidator") (
Validator validator;
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들을 출력할 수 있습니다.