[spring] custom validation annotation 만들기 By starseat 2022-02-03 13:31:25 java/spring Post Tags spring 프로젝트 중 기본적으로 제공하는 validation annotation 으론 부족한 경우가 있다. 아니 대부분 제공하고 정규식으로 표현 가능하다. 하지만 정규식으로 정의하는게 아닌 특별하게 명칭을 부여하거나 커스텀으로 생성하고 싶을때 참고하기 좋은 방법을 소개하고자 한다. `Item`이라는 `entity` class 가 있다고 예를 들어보자. `Item` class 에서 다른 항목은 제껴두고 `name` 만 보자. `name` 들어갈 값이 [영문, 숫자, -,] 라고 하면 `Item entity class` 의 `name` 의 정규식은 다음과 같이 할 것이다. - regexp=`[a-z|A-Z|0-9|_]` 예) Item.name 에 정규식 적용 ```java @Getter @Setter @Builder @Schema public class Item { private String id; @Pattern(regexp="^[a-z|A-Z|0-9|_]+$") private String name; ... } ``` 하지만 이 아이템 명에 적용한 패턴이 다른곳에서 쓰인다면 정규식을 계속 써 줘야 한다. 이럴 경우 `@Pattern(regexp="^[a-z|A-Z|0-9|_]+$")` 이 아닌 `ItemName` 이라는 `Validation Annotation` 을 생성하면 편하게 관리 가능할 것이다. 생성하는 것은 의외로 간단하다. ```java import javax.validation.Constraint; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.regex.Pattern; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.TYPE_USE; @Documented @Constraint(validatedBy = { ItemNamePattern.ItemNameValidator.class }) @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) public @interface ItemNamePattern { String message() default "invalid item name format."; String pattern() default "^[a-z|A-Z|0-9|_]+$"; Class>[] groups() default {}; Class extends Payload>[] payload() default {}; class ItemNameValidator implements ConstraintValidator { private String pattern; @Override public void initialize(ItemNamePattern constratintAnnotation) { this.pattern = constratintAnnotation.pattern(); } @Override public boolean isValid(String data, ConstraintValidatorContext context) { return Pattern.matches(pattern, data); } } } ``` 소스를 보면 대충 짐작이 될 것이다. `ItemNamePattern` 이라는 `Annotation` 을 생성하여 `ItemNameValidator` 의 `isValid` 로 검사한다. 구글링을 하면 자세한 설명과 다른 방법을 소개하는 블로그 들이 많아 난 필요로 하는 소스만 샘플로 작성하였다. 사용법은 위의 `Item` class 에서 `name` 에 `@ItemNamePattern` 을 표기해 주기만 하면 된다. ```java @Getter @Setter @Builder @Schema public class Item { private String id; @ItemNamePattern private String name; ... } ``` Previous Post [Effective Java 3/E] 04. 클래스와 인터페이스 Next Post [jdbc] mariadb 의 tinyint 사용시 주의점