데이터에 대한 유효성 검사라고 할 수 있다. 물론 클라이언트 레이어에서 적절한 유효성 검사가 이루어질 수도 있지만 서버가 받은 데이터는 대부분 데이터베이스에 저장되기 때문에 더욱더 데이터 무결성을 지킬 필요가 있다. 따라서 서버 또한 유효성 검사를 할 필요가 있다.
또한 자바에서는 null 값에 대해 접근하려고 할 때 null pointer exception이 발생하므로 더욱더 유효성 검사가 필요하다.
Spring Boot 기반의 웹 애플리케이션에서 유효성 검사를 위해 기본적으로 제공하는 어노테이션 중에 자주 사용되는 것들은 다음과 같다.
모듈에 의해 제공되는 어노테이션들은 속성에 어노테이션을 명시하기만 하면 되기 때문에 구체적인 설명은 넘어가도록 생략하겠다.
Custom Validation이란 말 그대로 직접 만든 유효성 검사 어노테이션을 뜻한다. 크게 두 가지 파일이 필요하다. 어노테이션 파일과 해당 어노테이션이 수행할 로직을 갖고 있는 클래스 파일이다.
@Constraint(validatedBy = {YearMonthValidator.class}) // YearMonthValidator 클래스를 사용해서 실제 유효성 검사를 수행
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) // 메서드, 속성, ... 등에 사용될 수 있음
@Retention(RUNTIME) // 런타임 시에도 유지되도록
public @interface YearMonth {
String message() default "yyyyMM 형식에 맞지 않습니다.";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
String pattern() default "yyyyMMdd";
}
public class YearMonthValidator implements ConstraintValidator<YearMonth, String> {
private String pattern;
@Override
public void initialize(YearMonth constraintAnnotation) {
this.pattern = constraintAnnotation.pattern();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
try {
LocalDate localDate = LocalDate.parse(value + "01", DateTimeFormatter.ofPattern(this.pattern));
} catch (Exception e) {
return false;
}
return true;
}
}
ConstraintValidator를 구현해 isValid 메서드에 실제 유효성 검사를 수행할 로직을 작성하면 된다. isValid 메서드의 첫 번째 매개변수는 유효성 검사 대상인 데이터다.
위 예제는 연도와 월을 6글자로 제한하는 어노테이션에 대한 유효성 검사이다. 때문에 value 값에 "01"을 추가적으로 붙여 this.pattern의 기본 값인 "yyyyMMdd" 형식에 맞는지 확인하고 있다.
정리
모듈에서 제공하는 기본적인 어노테이션을 통해 유효성 검사를 진행할 수도 있지만 직접 어노테이션을 만들어야 하는 경우도 있다.