今回は@Patternで指定する正規表現を使って、わかりやすい名前の独自入力チェック用アノテーションを作ってみます。
なお、STS3(3.9.6)+SpringBoot2.0+tymeleaf3.0迄動作確認しています。
@Patternを使う方法には欠点がある
Spring Boot +thymeleafの入力チェックでは、@Patternを使えば、大抵のことができるのですが、このやり方にはちょっと欠点があります。
それは、わかりづらいことです。
こんな感じの記述が、1箇所ならともかく、たくさんあると、ちょっと嫌です。
@Pattern(regexp = "^(https?|ftp)(:\\/\\/[-_.!~*\\'()a-zA-Z0-9;\\/?:\\@&=+\\$,%#]+)$")
やっぱり、@UrlValid とか @EmailValid とかのわかりやすい名前のアノテーションを使ってやれるにこしたことはありません。
ということで、今回は@Patternで指定する正規表現を使って、わかりやすい名前の独自入力チェック用アノテーションを作ってみます。
独自の入力チェックアノテーションを作ってみる
独自入力チェックアノテーションは、形式が決まってます。
今回、Eメールの正規表現パターンを使った独自アノテーション定義を作り、それを例にして形式を整理してみます。
今回の例にするアノテーション定義です。
import java.lang.annotation.*;
import javax.validation.*;
import javax.validation.constraints.Pattern;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;@Documented
@Constraint(validatedBy={})
@Target({FIELD,ANNOTATION_TYPE})
@Retention(RUNTIME)
@ReportAsSingleViolation
@Pattern(regexp="^([\\w])+([\\w\\._-])*\\@([\\w])+([\\w\\._-])*\\.([a-zA-Z])+$")
public @interface EmailValid {
String message() default "{0}はメールアドレスとして許可された形式ではありません。";
Class<?> groups() default {};
Class<? extends Payload> payload() default {};
@Target({FIELD,ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
public @interface List {
EmailValid value();
}
}
いろいろ、決め事があるので、整理していきます。
独自アノテーション定義は、public @interface で定義する
まず、独自アノテーション定義は、public @interface で定義します。
今回の例では、public @interface EmailValidなので、@EmailValidというアノテーションとして使います。
次に、このアノテーション定義をバリデーションで使うための、決め事にそってアノテーションを付与していきます。
- @Documented を固定で付与します。
- @Retention(RUNTIME) も固定で付与します。
エラーメッセージをの取得先を指定します
以下のアノテーションを付与すると、ここで「message default」で定義したエラーメッセージを使います。
付与しなかった場合は、もとのメッセージ(例えば@Patternを使ったときは、Patternで定義されているメッセージを使います。
@ReportAsSingleViolation
@Constraintで独自か再利用かを指定する
次に、@Patternの様な標準アノテーションを再利用・集約するか、独自にチェックを実装するかを@Constraintで指定します。
- @Constraint(validatedBy={})は。今回の例のように標準アノテーションを再利用・集約する場合の書き方です。独自実装でロジックを組むときは、その実装クラスを{}の中に指定します。
@Targetで設定する場所を指定する
次にアノテーションを設定する場所を@Targetで指定します。
- @Target({FIELD,ANNOTATION_TYPE})
上記の@Targetの{}内で指定可能な場所は以下があります。
- TYPE: インターフェース、クラス、列挙型などに付加する。
- CONSTRUCTOR: コンストラクタに付加する。
- FIELD: フィールド・列挙型の要素に付加する。
- METHOD: クラス等のメソッド、アノテーション定義のメソッド宣言に付加する。
- PARAMETER :パラメータ、メソッド宣言の引数の箇所に付加する。
- LOCAL_VARIABLE: ローカル変数に付加する。
- ANNOTATION_TYPE アノテーション定義に付加する。
今回の例では、Formクラスの変数のみにきかせるだけなので、FIELDとANNOTATION_TYPEにしているわけです。
メソッドを定義する
あと、アノテーション定義の中でメソッドを定義するのですが、ここの部分はほぼ固定的に書くものが決まっています。
まず、message()は、このアノテーションで表示するエラーメッセージを定義します。
String message() default "{0}はメールアドレスとして許可された形式ではありません。";
次の2つは、必ず定義しておかないといけませんが、特に変更する必要はありません。
Class<?> groups() default {};
Class<? extends Payload> payload() default {};
最後に、自分自身(例の場合だと EmailValidアノテーション定義)の配列を返すように書きます。
public @interface List {
EmailValid value();
}
これで決まった形式は終わりです。
作ったアノテーションを試してみる
今回は、独自ロジックを実装せず、標準アノテーションを再利用して使いやすくするだけなので、正規表現でメールフォーマットを検査する「@Pattern(regexp="^([\\w])+([\\w\\._-])*\\@([\\w])+([\\w\\._-])*\\.([a-zA-Z])+$")」を、そのまま書いています。
こうやって作った独自アノテーションを早速利用してみます。@Patternで書いていた部分を@EmailValidで置き換えます。
@EmailValid
private String chktest;public String getChktest() {
return chktest;
}public void setChktest(String chktest) {
this.chktest = chktest;
}
これで、Eメールアドレスとして駄目な@2つのパターンを入力してみます。
いけてるみたいです。
STS +Spring Boot +thymeleaf 関連記事
入力画面に関連する記事
参照画面・画面遷移に関連する記事
参照画面:テーブルを使い、行毎に色分けした一覧表を表示する。
入力チェックに関連する記事
入力チェック:@Patternと正規表現で独自チェックする。
入力チェック用アノテーション定義を自分で作る。(独自実装版)
データアクセス・その他に関連する記事