はじめてのBean Validation その2

の続き。

今回はカスタムバリデーションを作ってみる。

とはいえ、細かいバリデーションはアプリケーションのバリデーションとして実装すると思うので、数値チェックであるとか必須チェックとかシンプルな範囲だけだから、多少作ってしまったらそれだけでいいと思うけど。


今回は必須入力チェック専用のバリデータを作ってみる。Nullも長さゼロの文字列もどちらもはじくという処理。@NotNullと@Size(min=1)アノテーションをつければいいだけではあるが。作るクラスは2つ。

アノテーションとそのアノテーションに対応したバリデーション実装クラス。


これらのクラスは相互に参照するので普通に打ち込むと先に書いたほうがコンパイルエラーになるのでアノテーションからバリデーション実装クラスへの参照部分は最初はなしでやったほうがいいかもね。実装クラス側はジェネリクスアノテーション指定が必須なのでこちらは後にしたほうがいいでしょう。

ではアノテーションから。

@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy={RequiredValidator.class})//←ここが参照部分
public @interface Required {

    String message() default "必須ですぜ旦那";

    Class<?>[] groups() default {};

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

groupsとpayloadが必須。中身は空っぽでよい。


バリデーション実装クラス。

public class RequiredValidator implements ConstraintValidator<Required, String>{

    public void initialize(Required constraintAnnotation) {
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(value == null){
            return false;
        }
        if(value.isEmpty()){
            return false;
        }
        return true;
        
    }

}

isValidでの戻り値がfalseだとバリデーションエラーということになる。


使うときにはこのアノテーション(@Required)をフィールドにつけるだけ。



んで、ここまで書いておいてもっといい方法があるというのを書いてみる。

標準で実装されているバリデーションのアノテーションはどれもアノテーションにつけることができる。つまりこの指定をしてしまえば定型的な組み合わせによるものは実装クラスを作らなくてもよいということ。アノテーションのみでよい。

今回のは以下のようになる。

@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Size(min=1,message="必須")
@NotNull(message="必須")
@Constraint(validatedBy={})
public @interface Required {

    String message() default "ここはつかわれませんぜ";

    Class<?>[] groups() default {};

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

整数のみとか正の数のみとかIntegerの範囲内でとかよくあるのは作っておいたほうがいいかもしれない。