-------- バリデーション -------- agata baba -------- 2008-08-24 -------- {目次} *{{{#バリデーション}バリデーション}} *{{{#バリデーションの定義}バリデーションの定義}} *{{{#定義済みバリデーション}定義済みバリデーション}} *{{{#バリデーションのエラーメッセージ}バリデーションのエラーメッセージ}} *{{{#バリデーションルールのコピー}バリデーションルールのコピー}} *{{{#独自バリデーションの定義}独自バリデーションの定義}} *{{{#リクエストパラメータのバリデーション}リクエストパラメータのバリデーション}} *{{{#ユーザー定義のロジックによるバリデーション}ユーザー定義のロジックによるバリデーション}} {バリデーション} Cubby ではフォームから入力された値をバリデーションする仕組みが用意されています。 フォームから入力された値は HttpServletRequest#getParameterValues で返される値が String の配列であることからもわかるように、 全ての値を配列として取得できます。定義済みのバリデーションはこの配列に対してのバリデーションを行います。 また、フォームオブジェクトやデータベースを参照してデータ制約を検証する独自のバリデーションをプログラム上に定義することができます。 バリデーションの実行タイミングは{{{action.html#リクエストからアクション実行までのフロー}リクエストからアクション実行までのフロー}}を参照してください。 {バリデーションの定義} バリデーションの定義は Java コードで記述します。以下のように、アクションメソッドに対してバリデーションのルールを定義します。 [[1]]アクションに{{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html}ValidationRules}}型のプロパティを用意し、 定義したバリデーションのルールを取得できるようにします。 以下のように{{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html}DefaultValidationRules}}を継承して、 {{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html#initialize()}initialize}}メソッドをオーバーライドし、そのメソッドの中で {{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html#add(java.lang.String, org.seasar.cubby.validator.Validator...)}add}}メソッドを用いて フォームのフィールドごとにバリデーションのルールを追加します。 +------------------------------------------------------+ public class LoginAction extends Action { // バリデーションのルール public ValidationRules validationRules = new DefaultValidationRules() { @Override public void initialize() { // フィールド "userId" は必須入力で最大10文字まで add("userId", new RequiredValidator(), new MaxLengthValidator(10)); // フィールド "password" は必須入力で最大10文字まで add("password", new RequiredValidator(), new MaxLengthValidator(10)); } }; ... +------------------------------------------------------+ [[2]]アクションメソッドにアノテーション{{{cubby/apidocs/org/seasar/cubby/action/Validation.html}@Validation}}を定義し、{{{cubby/apidocs/org/seasar/cubby/action/Validation.html#rules()}rules}}でアクションメソッドと[[1]]で定義したバリデーションルールのプロパティを関連付けます。 入力検証でエラーを検出した場合は、アクションのプロパティ{{{cubby/apidocs/org/seasar/cubby/action/Action.html#errors}errors}}にメッセージが設定され、{{{cubby/apidocs/org/seasar/cubby/action/Validation.html#errorPage()}errorPage}}で指定されたページに遷移します。 +------------------------------------------------------+ // プロパティ「validationRules」をバリデーションのルールとして使用します。 // 検証エラー発生時は「confirm.jsp」に遷移します。 @Validation(rules = "validationRules", errorPage = "confirm.jsp") public ActionResult save1() { ... } } +------------------------------------------------------+ [] *{定義済みバリデーション} Cubby に定義済みのバリデーションクラスは以下のものがあります。 {{{cubby/apidocs/index.html?org/seasar/cubby/validator/ScalarFieldValidator.html}ScalarFieldValidator}} を実装しているクラスがひとつの要素を検証するバリデータ、 {{{cubby/apidocs/index.html?org/seasar/cubby/validator/ArrayFieldValidator.html}ArrayFieldValidator}} を実装しているクラスが配列全体を検証するバリデータとなっています。 *----------------------+--------------------------------------+ || クラス名 || 説明 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/ArrayMaxSizeValidator.html}ArrayMaxSizeValidator}} |配列の最大サイズを検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/ArrayMinSizeValidator.html}ArrayMinSizeValidator}} |配列の最小サイズを検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/DateFormatValidator.html}DateFormatValidator}} |日付に対する検証を行います。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/EmailValidator.html}EmailValidator}} |Eメールアドレスに対する検証を行います。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/EqualsValidator.html}EqualsValidator}} |指定した文字列と等しいかどうかを検証します。| *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/FileRegexpValidator.html}FileRegexpValidator}} |ファイルアップロードのファイル名が指定された正規表現にマッチするか検証します。| *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/MaxLengthValidator.html}MaxLengthValidator}} |最大文字数を検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/NumberValidator.html}NumberValidator}} |数値かどうかを検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/RangeLengthValidator.html}RangeLengthValidator}} |文字列の長さの範囲を指定して検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/RangeValidator.html}RangeValidator}} |数値の範囲を指定して検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/RegexpValidator.html}RegexpValidator}} |指定された正規表現にマッチするか検証します。| *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/RequiredValidator.html}RequiredValidator}} |必須検証します。 | *----------------------+--------------------------------------+ |{{{cubby/apidocs/org/seasar/cubby/validator/validators/TokenValidator.html}TokenValidator}} |2重サブミットを検証します。 | *----------------------+--------------------------------------+ 定義済みバリデーションクラス一覧 詳細は{{{cubby/apidocs/index.html?org/seasar/cubby/validator/validators/package-summary.html}APIドキュメント}}をご覧下さい。 *{バリデーションのエラーメッセージ} バリデーションのエラーメッセージは以下のルールで作成されます。 * メッセージキーを指定しない場合、パラメータ名がエラーメッセージ中の項目名のメッセージキーとして使用されます。 * メッセージキーを指定する場合、指定されたメッセージキーがエラーメッセージ中の項目名のメッセージキーとして使用されます。 * DefaultValidationRules のコンストラクタでキーの項目名のメッセージキーのプリフィックスを指定することができます。 * 各バリデーションのコンストラクタでメッセージキーを指定することで検証時のエラーメッセージを切り替えることもできます。 +------------------------------------------------------+ public class LoginAction extends Action { // 項目のメッセージキーを指定 public ValidationRules validation = new DefaultValidationRules() { @Override public void initialize() { // メッセージキー"userId"の値がエラーメッセージ中の項目名として使用されます。 add("userId", new RequiredValidator(), new MaxLengthValidator(10)); // メッセージキー"login.password"の値がエラーメッセージ中の項目名として使用されます。 add("password", "login.password", new RequiredValidator(), new MaxLengthValidator(10)); } }; // 項目名のメッセージキーのプリフィックスを指定 public ValidationRules validation2 = new DefaultValidationRules("login.") { @Override public void initialize() { // メッセージキー"login.userId"の値がエラーメッセージ中の項目名として使用されます。 add("userId", new RequiredValidator(), new MaxLengthValidator(10)); } }; // 各バリデーションにメッセージキーを指定 public ValidationRules validation3 = new DefaultValidationRules() { @Override public void initialize() { // メッセージキー"err.myrequired"がエラーメッセージとして使用されます。 add("password", new RequiredValidator("err.myrequired")); } }; ... } +------------------------------------------------------+ *{バリデーションルールのコピー} ほとんどが同じでいくつかの項目が異なる複数のルールを作りたい場合、以下のように他のルールをコピーして使用することができます。 +------------------------------------------------------+ public class LoginAction extends Action { // ベースのルール private ValidationRules baseValidationRules = new DefaultValidationRules() { @Override public void initialize() { add("userId", new RequiredValidator(), new MaxLengthValidator(10)); add("password", "login.password", new RequiredValidator(), new MaxLengthValidator(10)); } }; // ベースのルールに「nickname」の検証を追加 public ValidationRules validationRules1 = new DefaultValidationRules() { @Override public void initialize() { // baseValidationRulesのルールをコピーして追加 addAll(baseValidationRules); add("nickname", new RequiredValidator(), new MaxLengthValidator(10)); } }; // ベースのルールに「password2」の検証を追加 public ValidationRules validation2 = new DefaultValidationRules() { @Override public void initialize() { // baseValidationRulesのルールをコピーして追加 addAll(baseValidationRules); add("password2", new RequiredValidator(), new MaxLengthValidator(10)); } }; ... } +------------------------------------------------------+ {独自バリデーションの定義} *{リクエストパラメータのバリデーション} リクエストパラメータのバリデーションを独自に作成するには{{{cubby/apidocs/org/seasar/cubby/validator/ScalarFieldValidator.html}ScalarFieldValidator}} または{{{cubby/apidocs/org/seasar/cubby/validator/ArrayFieldValidator.html}ArrayFieldValidator}}を実装して作成します。\ 実装の方法は{{{cubby/xref/org/seasar/cubby/validator/validators/package-summary.html}それぞれのインターフェイスの実装クラス}}を参照してください。 *{ユーザー作成のロジックによるバリデーション} データベースアクセスなどのユーザー作成のロジックによるバリデーションを作成するには{{{cubby/apidocs/org/seasar/cubby/validator/ValidationRule.html}ValidationRule}}を実装して作成してください。 バリデーションルールを登録する際には {{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html#add(org.seasar.cubby.validator.ValidationPhase, org.seasar.cubby.validator.ValidationRule)}add}} メソッドの第一引数でバリデーションを実行するフェーズを指定できます。 バリデーションはフェーズごとに実行されます。 あるフェーズのバリデーションでエラーがあった場合は次のフェーズのバリデーションを実行せずにエラー処理へ移行します。 デフォルトでは {{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html#DATA_TYPE}DATA_TYPE(データ型を検証するフェーズ)}} と {{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html#DATA_CONSTRAINT}DATA_CONSTRAINT(データ上の制約を検証するフェーズ)}} が定義されていて、 フェーズを指定しない場合は DATA_TYPE のフェーズに追加されます。 +------------------------------------------------------+ public UserDao userDao; public String userId; public String password; public Map sessionScope; public ValidationRules loginValidation = new DefaultValidationRules( "login.") { @Override public void initialize() { add("userId", new RequiredValidator()); add("password", new RequiredValidator()); // userId と password の双方が入力されたことが確認されてから UserValidationRule // を実行したいので、フェーズに DATA_CONSTRAINT に指定します。 add(DATA_CONSTRAINT, new UserValidationRule()); } }; private class UserValidationRule implements ValidationRule { public void apply(Map params, Object form, ActionErrors errors) throws ValidationException { User user = userDao.findByIdAndPassword(userId, password); if (user == null) { // エラーを検出した時、次のバリデーションを実行しないようにするためには // ValidationException をスローしてください。 throw new ValidationException("ユーザIDかパスワードが違います。", "userId", "password"); } sessionScope.put("user", user); } } +------------------------------------------------------+ *{アクションメソッドからエラーページへの遷移} アクションメソッドでエラーを検出した場合は {{{cubby/apidocs/org/seasar/cubby/validator/DefaultValidationRules.html#ValidationException}ValidationException}} をスローすることで、処理を中断してエラーページへ遷移させることができます。