SAStrutsの入力チェックの順序
SAStrutsの入力チェックの実装手段は以下の3つがある。
1)アノテーション…入力項目ごとに複数定義できる。
2)検証用メソッド…ひとつのアクションごとに複数定義できる。
3)アクションメソッド…アクションに対して定義できる。
1,2,3の順序
デフォルトでは、入力チェックの順序は、1 -> 2-> 3 の順になる。
1と2の順序は、Excecuteアノテーションのvalidateで、順序の入れ替えができる。
デフォルトでは、1、2、3 は、その前段でエラーが発生したら、次のチェックは実施されない。
ただし、ExcecuteアノテーションのstopOnvalidationErrorで変更できる。
3は、1,2の入力チェックが全てOKのときだけ実行される。
2が複数あるときの順序
2 が複数ある場合は、Excecuteアノテーションのvalidateで順序が指定できる。
2が複数あるとき、デフォルトでは、その前段でエラーが発生したら、次のチェックは実施されない。
ただし、ExcecuteアノテーションのstopOnvalidationErrorで変更できる。
1が複数あるときの順序
アノテーションの実行順に関しては、2つに分けて考える。
1-1) 項目(メンバ変数)ごとの順序
1-2) アノテーションごとの順序
1-1) 項目(メンバ変数)ごとの順序
Javaのソース上のメンバ変数の定義順で入力チェックが実行される。
そして、入力チェックのエラーが複数ある時は、すべてのメッセージが画面に表示される。
画面の表示順は、入力チェックの実行順(つまり、メンバ変数の定義順)になる。
ただし、メンバ変数の順序は、SunのJVMが、たまたまそう動くだけで、その順序が保障されているわけではない。
途中で入力エラーになっても、すべてのメンバ変数で入力チェックが実施される。(この挙動は変更できなそう。)
エラーメッセージの実行順は、org.seasar.struts.customizer.ActionCustomizer#setupValidator の中で、メンバ変数と、アノテーションでforで回しながら、入力チェックのコンフィグ情報を構築しているところがあるので、この部分をいじるのが手っ取り早そう。(実行順を変えれば、表示順も同じように変わる。)
エラーメッセージの表示順だけの変更なら、html:errors タグを使っているなら、org.apache.struts.taglib.html.ErrorsTag をいじってしまうのが手っ取り早い。
ちなみに、エラーメッセージそのものは、org.apache.struts.action.ERROR で、requrest の属性に設定されている。
空文字入力時の入力チェックの挙動
デフォルトで用意されているバリデータアノテーションは、空文字が入力されたとき、
Required アノテーション -> 入力エラー
Required 以外 -> 入力OK
になる。
例えば、
@Required @MaxLength(maxlength="32") @Mask(mask="^[0-9]+$") public hoge;
としているとき、hoge に入力がないときは、Requiredアノテーションだけ入力エラーになる。
一見、MaxLengthアノテーションや、Maskアノテーションでもエラーになるように見える。
これは、Requiredアノテーションがエラーになったから、次のMaxLength、Maskが実行されなかったわけではない。
MaxLength、Mask は実行されるが、空文字が入力されたときは、強制的に、入力OKとしているため、Required だけ入力エラーが発生することになる。
この辺は、org.apache.struts.validator.FieldChecks の中の、GenericValidator.isBlankOrNull() を使っている部分をみればわかる。
validateMaskは、isBlankOrNull が true のときは、チェックをせずにそのまま終了している。
(今気づいたけど、validateMaxLength の実装は怪しい。空文字確認を、isBlankOrNull ではなくて、value != null でチェックしている。。)
まとめ
特にあれこれしていない限りは、SAStruts の入力チェックの挙動は以下のようになる。
1) 複数のメンバ変数があるときは、メンバ変数の定義順に 実行される。
2) メンバ変数に複数のアノテーションがあるときは、 アノテーションの定義順に実行される。
4)定義されているアノテーションは、常に全て実行され、Requiredアノテーション以外は、空文字は入力OKになる。
5)複数の入力エラーがあるとき、画面の表示順は、実行順と同じになるが、保障されているわけではない。
6)検証メソッドは、アノテーションのチェックがすべて成功したら実行される。
7)アクションメソッドは、アノテーション、検証メソッドのチェックがすべて成功したら実行される。