目次へ

15.2. 独自の検証ルールの追加

validator機能では提供されている検証ルールだけでなく、独自のものを追加することもできます。ここでは単純に「a」という文字であるかどうかをチェックする検証ルールを作成します。

始めに検証を行うクラスとメソッドを作成します。クラス名に制約はありませんが、java.io.Serializableを実装するようにしてください。メソッド名にも制約はありませんが、クラスメソッドにする必要があります。また引数は次の5つにするのが一般的です。返り値には制約がありませんので、voidで良いでしょう。

引数のクラス名 説明
java.lang.Object 検証対象となっているActionForm
org.apache.commons.validator.ValidatorAction この検証ルールに関する設定を格納したオブジェクト
org.apache.commons.validator.Field この検証ルールを使用した検証に関する設定を格納したオブジェクト
org.apache.struts.action.ActionErrors エラーメッセージを格納するActionErrors
javax.servlet.HttpServletRequest HTTPリクエスト

それでは「a」という文字であるかどうかをチェックする検証クラスを作成します。

package sample;
  
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.validator.Resources;
  
public class ValidateA implements Serializable {
  public static void validate(Object bean, ValidatorAction action,
                              Field field, ActionErrors errors,
                              HttpServletRequest request) {
    // ActionFormから検証対象となっているプロパティの値を文字列として取り出す
    String value=ValidatorUtil.getValueAsString(bean, field.getProperty());

    // 値がNULLか空行であるか確認
    if(!GenericValidator.isBlankOrNull(value)){
      // 値が「a」と同じであるか確認
      if(!value.equals("a")){
        // エラーメッセージを取り出しActionErrorsに格納
        errors.add(field.getKey(), Resources.getActionError(request, action, field));
      }
    }
  }
}

まず始めにorg.apache.commons.validator.ValidatorUtilクラスのgetValueAsStringクラスを用いて、ActionFormから検証対象となっているプロパティの値を文字列として取り出しています。FieldのgetPropertyメソッドは検証対象のプロパティ名を設定ファイルから読み込むものです。<field>要素のproperty属性の値が返されます。以下で指定されているActionFormでこの検証ルールが使用されるとしたら、「name」プロパティがその対象となります。Fieldクラスは<field>要素および<field>要素内に設定されている内容を管理するクラスです。

...
<form name="productForm">
  <field property="name" depends="required, validateA">
    <msg name="required" key="name.required" />
    <msg name="validateA" key="name.invalidate" />
  </field>
</form>
...

org.apache.commons.validator.GenericValidatorはStrutsで提供されている検証ルールのほとんどを提供するクラスです。isBlankOrNullメソッドは文字列がNULLか空行である場合にtrueを返すメソッドで、サンプルの場合にはそうでない、つまり何らかの文字列が指定されている場合にifブロックの中が実行されます。

最後に値が「a」でなかった場合に行われている処理について説明します。エラーの場合にはエラーメッセージを表示する必要があるので、ActionErrorsにActionErrorを登録しています。ActionErrorはorg.apache.struts.validator.ResourcesのgetActionErrorメソッドで取得しています。Resourcesメソッドは、設定ファイルの対応する<msg>要素で指定されているActionErrorを返します。

FieldのgetKeyメソッドは、通常はgetPropertyメソッドと同じく検証対象のプロパティ名を返します。<field>要素にindexedListProperty属性が指定された場合、それと組み合わせた値を返す点がgetPropertyメソッドと異なります。getPropertyメソッドはindexedListProperty属性が指定されても、property属性の値を返します。つまりプロパティ名(indexedListPropertyが指定されている場合はそれを組み合わせた名前)で、ActionErrorを登録していることとなります。

検証クラスの作成が完了したら、それを使用するための設定を行います。設定はvalidator-rules.xmlに行っても構わないのですが、通常はもう1つ別の設定ファイルを作成します。ここでは新たに作成する設定ファイル名を「orig-validator-rules.xml」とします。まずstruts-config.xmlのValidatorPlugInに設定ファイルを追加します。

...
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
  <set-property property="pathnames"
                value="/WEB-INF/validator-rules.xml,/WEB-INF/orig-validator-rules.xml,
                       /WEB-INF/validation.xml" />
</plug-in>
...

続いてorig-validator-rules.xmlを作成します。中身はvalidator-rules.xmlに従ったものとなります。以下は今回作成したクラスに対する設定です。

<!DOCTYPE form-validation PUBLIC
          "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN"
          "http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
<form-validation>
  <global>
    <validator name="validateA"
               classname="sample.ValidateA"
               method="validate"
               methodParams="java.lang.Object,
                             org.apache.commons.validator.ValidatorAction,
                             org.apache.commons.validator.Field,
                             org.apache.struts.action.ActionErrors,
                             javax.servlet.http.HttpServletRequest"
               msg="errors.invalidate">
    </validator>
  </global>
</form-validation>

検証ルールの設定は、<validator>要素を用いて行います。<validator>要素は<global>要素の中に定義します。validator-rules.xmlの<global>要素内に定義しても問題ありませんが、その場合はstruts-config.xmlの設定変更は不要です。以下は<validator>要素の属性一覧です。methodParamsには節の最初に説明したメソッドの引数を順に指定します。なお検証メソッドの引数に指定されるValidatorActionは、<validator>要素に設定された値を管理するオブジェクトです。

属性名 必須 説明
name 検証ルール名
classname 検証を実行するクラスを完全限定名で指定
method 検証を実行するメソッド名
methodParams 検証メソッドに渡す引数の型を、コンマ「,」区切りで指定
msg 検証に失敗した場合に追加するActionErrorの検索キー。この検証ルールにおけるActionError検索キーのデフォルトの値となる。

最後に追加した検証ルールを使用する設定を行います。validation.xmlの使用したいActionFormのプロパティに対応する<field>要素のdepends属性に指定するだけです。以下はその例です。requiredルールと兼用して使用する設定を行っています。なおこれは節の途中で使用した例と同じものです。

...
<form name="productForm">
  <field property="name" depends="required, validateA">
    <msg name="required" key="name.required" />
    <msg name="validateA" key="name.invalidate" />
  </field>
</form>
...

(実習課題2)

実習課題1のWebアプリケーションを改良しなさい。

  • 偶数であることをチェックする検証ルールを作成し、int型のプロパティに対して適応すること。

解答例はこちら

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp