以前、Javaの自作アノテーションを作成する方法をブログにしました。しかし、自作アノテーションに定義した変数を取り出して、バリデーションを行う方法がちょっとだけ面倒だったので、ブログに残します。
環境
- Java
- 17
前提
テストする方法は、こちらの記事を参考にしてください。
ユースケース
- 文字数バリデーションをかけたい
今回の例では、バイト数と文字数のチェックをかけるアノテーションを付与します。
// 30バイト、10文字まで許容 @AppStringValid(byteCount = 30, wordCount = 10) private String targetStr;
対応
アノテーションに必要な変数を定義してください。今回は、byteCount
, wordCount
という変数で許容するバイト数、文字数を定義します。
@Documented @Constraint(validatedBy = {AppStringValidator.class}) @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface AppStringValid { String message() default "文字数が規定より超えています。"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; // チェックしたいバイト数と文字数 int byteCount() default 0; int wordCount() default 0; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @interface List { AppStringValid[] value(); } }
前回の記事にて、ConstraintValidator
を実装しました。実際のバリデーションをかけるisValid
メソッドの第2引数のConstraintValidatorContext
にアノテーションの情報が含まれているため、キャストしながら値を取得します。
文字だと長いので、ソースコードを確認してください。
@Override public boolean isValid(String value, ConstraintValidatorContext context) { var annotationDescriptor = ((ConstraintDescriptorImpl) ((ConstraintValidatorContextImpl) context).getConstraintDescriptor()).getAnnotationDescriptor(); // アノテーションでbyteCountに30を渡したので、30を取得できます int byteCount = (Integer) annotationDescriptor.getAttribute("byteCount"); int wordCount = (Integer) annotationDescriptor.getAttribute("wordCount"); ... 省略 }
ソースコード
終わりに
正直、IntelliJ IDEAがいい感じにキャストしてくれていたので、特に悩むことなく実装自体はできました。
ただ、本当にここまでキャストしなければいけないのかが疑問です。何かしらの、AnnotationUtil
みたいな便利クラスでいい感じに取得できないのかな…。