[cubby]入力検証の仕様
Urlマッピングの仕様なかなかいい感じに仕様が固まったので、次は入力検証の仕様を決めたいです。またいろいろとご意見いただけると嬉しいっす。
Webフレームワークの入力検証としては、以下の項目を考慮する必要があると思っています。
【基本】
- コントローラの実行前にパラメータの入力値を検証できる
- 1入力項目に対して、複数の検証を組み合わせて指定可能
- 検証は「入力パラメータ」の値に対して行う。(入力フォームクラスに対してではない)
- 入力値を受け取る入力フォームクラス(StrutでいうところのActionForm)に対して、複数の検証パターンを画面ごとに切り替えて指定可能
【検証エラー発生時】
- 「 入力値を受け取る入力フォーム用のクラス」からではなく、入力パラメータから入力画面を復元できる。例:数値項目(入力フォームクラス上は数値フィールド)に「AAA」と入力した場合、エラー後の入力画面復元時は入力フィールドに「AAA」と表示されるべき。(編集開始時は画面では通常は入力フォームクラスから値を復元するはずなので、このあたりを透過的に切り替えてくれる必要がある)
- 検証エラーが発生した場合の、戻り先を指定できる(struts-configでいうところのinput属性)
- 検証エラー発生時のエラーメッセージを変更できる。エラーメッセージ中のキーなども。
- 業務的な入力エラー(DBを見て、エラーがきまるタイプ)をサポートするか?Strutsではサポートしてないので、アクションクラス内で検証する必要がある。
cubbyでは、設定ファイルによる検証設定は行いたくないので、入力フォーム用のクラスに記述します。アノテーションによる定義は(今のところ)おこなわず、コードでガリガリ書くスタイルにしています。
■入力フォームクラス
@LabelKey("login.") public class LoginDto { // フィールド名「VALIDATORS」がデフォルトの検証セット public static Validators VALIDATORS = new Validators(); static { VALIDATORS.add("userId", new Required(), new MaxLength(8)); VALIDATORS.add("password", "key.password", new Required(), new MaxLength(10)); } public String userId; public String password; ... 以下アクセサメソッド }
■コントローラクラス
public class LoginController { public LoginDto loginDto = new LoginDto(); @Form("loginDto") @Validation(errorPage="login.jsp") public ActionResult login_process() { ... return new Redirect("/todo/list"); } }
■デフォルト以外の入力検証セットを指定する場合
@Validation(errorPage="login.jsp", validators="HOGE_VALIDATORS")
- @Validationがあると、アクションメソッドの実行前に入力検証が実行されます。
- 入力検証をコードで書くのと、アノテーションで書くのは、どっちがいいでしょうか?
- デフォルトの入力検証フィールド名が「VALIDATORS」って「ださく」ないでしょうか?
- @Form("this")とすることで、コントローラクラス自体を入力フォームクラスにすることも可能です。
- @LabelKeyをつけると、プロパティファイルのキー「login.userId」を項目名として、エラーメッセージを作成します。省略するとキー「userId」を見ます。パスワードの場合は、プロパティのキーを指定しているのでキー「key.password」を項目名として使用します。
- その他なんなりと。
URIのマッピングの仕様その3
こんな感じにしました。
@Url("/{userId}/todo/{todoId,[0-9]}")
babaさんの仕様に型も指定できる仕様を追加しました。
上記の場合、{todoId}の部分には数値のみが引っかかります。
型の指定がない場合、「[0-9a-zA-Z]」を指定したのと同様になり、
例では「/([0-9a-zA-Z])/todo/([0-9])」という意味になります。
あと、2つのアクションのURLマッピングにマッチする場合の対応なども、考える必要がありそうです。正規表現部分の優先度が低いほうがいいんでしょうね。
1.@Url("/user/list") 2.@Url("/user/{userId}")
この場合、正規表現でない1.のほうがマッチの優先度が高いとかね。