[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.のほうがマッチの優先度が高いとかね。