☕️ java

커스텀 validation 만들기

beomsic 2023. 1. 28. 17:46

스프링 프레임워크가 기본적으로 제공하는 Validator Annotation으로 충분하지 않을 수 있다.

필요에 따라 직접 Validator를 구현해야 하는 경우가 생길 수 있다.

❗Annotation


Custom Constraint Annotation을 만들 때에는

  • message
  • groups
  • payload

위 3개는 꼭 정의를 해주어야 한다.

@Constraint(validatedBy = PasswordValidator.class)
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PasswordValidation {

  String message() default "Password is not validate";

  // 사용자들이 targeted group을 커스텀하기 위해 사용
  Class<?>[] groups() default {}; 

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

}

 

📚 @Constraint

  • 애노테이션을 Bean Validation Constraint로 만들어주는 애노테이션이다.
  • 사용자가 원하는 Constraint와 Validation을 만들어 적용할 수 있다.
  • message, groups, payload 속성값을 반드시 가져야 한다.


📖 message

  • 메시지 관리를 위해 사용


📖 groups

  • 상황별 validation 제어를 위해 사용
  • ex) insert 하는 경우, update 하는 경우 validation를 구분 짓고자 할 때


📖 payload

  • 사용자가 추가 정보를 위해 전달할 수 있는 값
  • 주로 심각도를 나타낸다.

 

❗Constraint Validator 구현 클래스


public class PasswordValidator implements ConstraintValidator<PasswordValidation, String> {

  private static final int MIN_SIZE = 8;
  private static final int MAX_SIZE = 20;
  private static final String REGEX_PASSWORD =
      "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@$!%*#?&])[A-Za-z[0-9]$@$!%*#?&]{" + MIN_SIZE
      + "," + MAX_SIZE + "}$";

  @Override
  public void initialize(PasswordValidation constraintAnnotation) {
  }

  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {

    boolean isValidPassword = value.matches(REGEX_PASSWORD);

    if(!isValidPassword) {
      context.disableDefaultConstraintViolation();
      context.buildConstraintViolationWithTemplate(
          MessageFormat.format(
              "{0}자 이상의 {1}자 이하의 숫자, 영문자, 특수문자를 포함한 비밀번호를 입력해주세요"
              , MIN_SIZE
              , MAX_SIZE))
          .addConstraintViolation();
    }
    return isValidPassword;
  }
}

 

📖 initialize()

  • annotation에 있는 정보를 멤버변수로 저장해 isValid() 에서 사용할 수 있다.


📖 isValid()

  • 정의하고자하는 validation logic이 정의된다.

 

📌 사용


 

@PasswordValidation
private String password;

 

참고자료

https://meetup.nhncloud.com/posts/223

https://kapentaz.github.io/java/Java-Bean-Validation-제대로-알고-쓰자/#

https://velog.io/@livenow/Java-커스텀-애노테이션으로-Password규칙-적용하기

https://reflectoring.io/bean-validation-with-spring-boot/

https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/