Getting started with JSR 303 (Bean Validation) – part 2
Creating custom constraint annotations
カスタムバリデーション用アノテーションの作成を説明します。
まず、カスタムのアノテーションを定義します。
アノテーションには以下のアノテーションを付加する必要があります。
・@Target( { METHOD, FIELD, ANNOTATION_TYPE }) :アノテーションを付加する対象をメソッド、フィールド、アノテーションとして指定します。
・@Retention(RUNTIME):バイトコードにアノテーションを含めます。
・@Constraint(validatedBy = MaxValidator.class):アノテーションの検証用クラスを指定します。検証用クラスは後ほど説明します。
次に必須のアノテーションプロパティを定義します。
String message() default "{validator.max}"; String型のmessageプロパティを定義します。 デフォルトはValidationMessages.propertiesファイルのキーで定義するのを推奨します。プロパティファイルのキーは"{}"で定義します。
Class[] groups() default {}; Classの配列型でgroupsプロパティを定義します。デフォルトは空でよいですが、Defaultインターフェースが内部的に適用されます。
※当初の仕様ではClassではなくString型での仕様が提案されていました。確かにClassの方がタイプセーフに記述できたり、集約できたりとメリットもあるのですが、私としてはグループに対していちいちクラス(インターフェース)を一つ一つ定義するのは冗長に感じてしまいます。また、Classの場合は動的にグループを定義することに対しては難しいのですが、逆にStringの場合だと容易です。Classの場合とStringの場合とではそれぞれ一長一短なのですが個人的にはStringが好みです。
Click framework のアクションリスナ、URLでのメソッドリゾルブを考えるとStringの方が他のフレームワークとの連携もしやすいだろうと考えるのもその理由です。
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; @Target( { METHOD, FIELD, ANNOTATION_TYPE }) //アノテーションを付加する対象を指定 @Retention(RUNTIME) @Constraint(validatedBy = MaxValidator.class) //検証用クラスの指定 public @interface Max { String message() default "{validator.max}"; //メッセージプロパティ Class<?>[] groups() default {}; //グループプロパティ long max(); //独自のプロパティ }
次に、検証用のクラスを定義します。まず、ConstraintValidatorインターフェースを実装します。
"
処理は最初に"initialize"メソッドが呼ばれ、次に"isValid"メソッドが呼ばれます。
そのため独自のプロパティがある場合はかならず"initialize"メソッドにて処理する必要があります。
その後、フレームワークによって"isValid"メソッドが呼ばれますが、検証値が不正な場合はfalseを返却する
用にします。そうでない場合は正常として処理されます。
検証用のクラスの記述が完了したら、検証用アノテーションの@Constraint(validatedBy = MaxValidator.class)
に記述します。
public class MaxValidator implements ConstraintValidator<Max, Long> { long max; public void initialize(Max constraintAnnotation) { max = constraintAnnotation.max(); //比較値を初期化する } public boolean isValid(Long obj, ConstraintValidatorContext constraintContext) { if (obj > max ){ return false; //不正な場合はfalseを返す } else { return true; } } }
以上でカスタムアノテーションの作成は完了です。プロパティに付加して利用します。