きり丸の技術日記

技術検証したり、資格等をここに残していきます。

Javaの自作アノテーションのプロパティの値を取得する(ConstraintValidator)

以前、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みたいな便利クラスでいい感じに取得できないのかな…。

類似情報