Spring Boot Custom Validation 어노테이션 만들기

Spring Hibernate Validator에 대해서 이해가 부족하다면 다음 글을 먼저 읽는 것을 추천합니다.

Spring Boot Hibernate Validator와 Data Binding: 데이터 유효성 검사와 데이터 연결 — INTP 개발자 (tistory.com)

 

Spring Boot Hibernate Validator와 Data Binding: 데이터 유효성 검사와 데이터 연결

Validation이란? 유효성 검증으로 전달 받은 데이터 객체의 내용에서 잘못된 내용이 있는지 유효성을 확인합니다. Spring은 주로 다음 두 가지 방식으로 유효성 검증을 합니다. Java Bean Validation Spring v

yeo-computerclass.tistory.com


Custom Validation 어노테이션

@NotBlank나 @Email, @Size 등과 같은 Validation 어노테이션을 만들기 위해서는  ConstraintValidator 인터페이스를 구현해야합니다.

 

아래 예제로 전화번호가 "010-XXXX-XXXX" 형식으로 들어오는지를 검증하는 어노테이션을 만들겠습니다.

 

Custom 어노테이션 클래스 생성

먼저, Custom 어노테이션 클래스를 생성합니다.

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface PhoneNumber {

    String message() default "핸드폰 번호 형식이 아닙니다. ex) 010-XXXX-XXXX";
    
    String pattern() default "^010-\\d{4}-\\d{4}$";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

 

ConstraintValidator 작성

해당 어노테이션의 유효성을 검사하는 ConstraintValidator를 작성합니다.

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class PhoneNumberValidator implements ConstraintValidator<PhoneNumber, String> {

    private String pattern;

    @Override
    public void initialize(PhoneNumber constraintAnnotation) {
        this.pattern = constraintAnnotation.pattern();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 전화번호가 지정된 패턴과 일치하는지 검증
        return value != null && value.matches(pattern);
    }
}

 

 

 

위와 같이 작성하면 우리는 다음과 같이 Custom Validation 어노테이션을 사용할 수 있습니다.

phoneNumber로 들어온 값이 우리가 지정한 패턴인 '010-XXXX-XXXX'이 아닌 경우 "핸드폰 번호 형식이 아닙니다. ex) 010-XXXX-XXXX"라는 default 메시지를 출력합니다.

public class User {
    
    // ...
    
    @PhoneNumber
    private String phoneNumber; 
}

 

 

기존 Validation 어노테이션 적용하기

Custom Validation 어노테이션에 기존 Validation 어노테이션을 사용하여 규칙을 강제할 수도 있습니다.
예를 들어, phoneNumber에 어떠한 문자열 값도 비어있지 않도록 강제하고 싶으면 Custom Validation 어노테이션을 생성할 때 다음과 같이 @NotBlank를 적용하여 작성할 수 있습니다.

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
@NotBlank   // 기존 Validation 어노테이션 추가
public @interface PhoneNumber {

    String message() default "핸드폰 번호 형식이 아닙니다. ex) 010-XXXX-XXXX";
    
    String pattern() default "^010-\\d{4}-\\d{4}$";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}