バリデーション

Cubby ではフォームから入力された値をバリデーションする仕組みが用意されています。

フォームから入力された値は HttpServletRequest#getParameterValues で返される値が String の配列であることからもわかるように、 全ての値は配列として取得できます。この配列に対してバリデーションを行います。

また、それ以外にもフォームオブジェクトやデータベースを参照する独自のバリデーションをプログラム上に定義することができます。

バリデーションの定義

バリデーションの定義は Java コードで記述します。以下のように、アクションメソッドに対してバリデーションのルールを定義します。

  1. アクションにValidationRules 型のプロパティを用意し、 定義したバリデーションのルールを取得できるようにします。

    以下のようにDefaultValidationRules を継承して、 initialize メソッドをオーバーライドし、そのメソッドの中で 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. アクションメソッドにアノテーション@Validation を定義し、rules でアクションメソッドと[[1]]で定義したバリデーションルールのプロパティを関連付けます。

    入力検証でエラーを検出した場合は、アクションのプロパティerrors にメッセージが設定され、errorPage で指定されたページに遷移します。

      // プロパティ「validationRules」をバリデーションのルールとして使用します。
      // 検証エラー発生時は「confirm.jsp」に遷移します。
      @Form
      @Validation(rules = "validationRules", errorPage = "confirm.jsp")
      public ActionResult save1() {
        ... 
      }
    
    }

定義済みバリデーション

Cubbyで定義済みのバリデーションクラスは以下のものがあります。

ScalarFieldValidator を実装しているクラスがひとつの要素を検証するバリデータ、 ArrayFieldValidator を実装しているクラスが配列全体を検証するバリデータとなっています。

クラス名 説明
ArrayMaxSizeValidator 配列の最大サイズを検証します。
ArrayMinSizeValidator 配列の最小サイズを検証します。
DateFormatValidator 日付に対する検証を行います。
EmailValidator Eメールアドレスに対する検証を行います。
EqualsValidator 指定した文字列と等しいかどうかを検証します。
FileRegexpValidator ファイルアップロードのファイル名が指定された正規表現にマッチするか検証します。
MaxLengthValidator 最大文字数を検証します。
NumberValidator 数値かどうかを検証します。
RangeLengthValidator 文字列の長さの範囲を指定して検証します。
RangeValidator 数値の範囲を指定して検証します。
RegexpValidator 指定された正規表現にマッチするか検証します。
RequiredValidator 必須検証します。
TokenValidator 2重サブミットを検証します。
定義済みバリデーションクラス一覧

詳細はAPIドキュメント をご覧下さい。

バリデーションのエラーメッセージ

バリデーションのエラーメッセージは以下のルールで作成されます。

  • メッセージキーを指定しない場合、パラメータ名がエラーメッセージ中の項目名のメッセージキーとして使用されます。
  • メッセージキーを指定する場合、指定されたメッセージキーがエラーメッセージ中の項目名のメッセージキーとして使用されます。
  • DefaultValidationRules のコンストラクタでキーの項目名のメッセージキーのプリフィックスを指定することができます。
  • 各バリデーションのコンストラクタでメッセージキーを指定することで検証時のエラーメッセージを切り替えることもできます。
    public class LoginAction extends Action {
    
      // 項目のメッセージキーを指定
      public static 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 static ValidationRules VALIDATION2 = new DefaultValidationRules("login.") {
        @Override
        public void initialize() {
          // メッセージキー"login.userId"の値がエラーメッセージ中の項目名として使用されます。
          add("userId", new RequiredValidator(), new MaxLengthValidator(10));
        }
      };
    
      // 各バリデーションにメッセージキーを指定
      public static ValidationRules VALIDATION3 = new DefaultValidationRules() {
        @Override
        public void initialize() {
          // メッセージキー"err.myrequired"がエラーメッセージとして使用されます。
          add("password", new RequiredValidator("err.myrequired"));
        }
      };
    
      ...
    }

バリデーションルールのコピー

ほとんどが同じでいくつかの項目が異なる複数のルールを作りたい場合、以下のように他のルールをコピーして使用することができます。

public class LoginAction extends Action {

  // ベースのルール
  public static ValidationRules BASE_VALIDATION = new DefaultValidationRules() {
    @Override
    public void initialize() {
      add("userId", new RequiredValidator(), new MaxLengthValidator(10));
      add("password", "login.password", new RequiredValidator(), new MaxLengthValidator(10));
    }
  };

  // ベースのルールに「nickname」の検証を追加
  public static ValidationRules VALIDATION1 = new DefaultValidationRules() {
    @Override
    public void initialize() {
      // BASE_VALIDATIONのルールをコピーして追加
      getRules().addAll(BASE_VALIDATION.getRules());
      add("nickname", new RequiredValidator(), new MaxLengthValidator(10));
    }
  };

  // ベースのルールに「password2」の検証を追加
  public static ValidationRules VALIDATION2 = new DefaultValidationRules() {
    @Override
    public void initialize() {
      // BASE_VALIDATIONのルールをコピーして追加
      getRules().addAll(BASE_VALIDATION.getRules());
      add("password2", new RequiredValidator(), new MaxLengthValidator(10));
    }
  };
  ...
}

独自バリデーションの定義

リクエストパラメータのバリデーション

リクエストパラメータのバリデーションを独自に作成するにはScalarFieldValidator またはArrayFieldValidator を実装して作成します。
実装の方法はそれぞれのインターフェイスの実装クラス を参照してください。

業務ロジックによるバリデーション

データベースアクセスなどの業務ロジックによるバリデーションを作成するにはValidationRule を実装して作成してください。

  public String userId;
  public String password;
  public Map<String, Object> sessionScope;

  public ValidationRules loginValidation = new DefaultValidationRules(
      "login.") {
    @Override
    public void initialize() {
      add("userId", new RequiredValidator());
      add("password", new RequiredValidator());
      add(new UserValidationRule());
    }
  };

  private class UserValidationRule implements ValidationRule {

    public void apply(Map<String, Object[]> params, Object form,
        ActionErrors errors) throws ValidationException {
      if (userId == null || password == null) {
        return;
      }
      User user = findUser(userId, password);
      if (user != null) {
        sessionScope.put("user", user);
      } else {
        errors.add("ユーザIDかパスワードが違います。", "userId", "password");
      }
      sessionScope.put("user", user);
    }

  }