バリデータの自作

Strutsのソース配布に含まれるorg.struts.validator.FieldChecks クラスなどのソースコードをまねて、バリデータを自分で作ってvalidation.xml に組み込むこともできます。以下に簡単な手順をご紹介します。

  1. まず、バリデータのクラスを書きます。 これはjava.io.Serializableを実装したクラスで、 public staticなメソッドを1つ以上用意します。 メソッド1つ1つが互いに独立した固有の検証を行います。 それらの戻り値はboolean(OKなら真、NGなら偽)ですが、 検証と同時に値を修正して返す場合は、そのデータ型でもよいようです。

    package shiten.struts.validator;
    
    import java.io.Serializable;
    import java.util.StringTokenizer;
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.commons.validator.Field;
    import org.apache.commons.validator.ValidatorAction;
    import org.apache.commons.validator.ValidatorUtil;
    import org.apache.struts.action.ActionMessages;
    import org.apache.struts.validator.Resources;
    
    public class ExampleValidator implements Serializable {
    
        /**
         *  Return <code>true</code> if the specified object is a String or a <code>null</code>
         *  value.
         *
         * @param o Object to be tested
         * @return The string value
         */
        protected static boolean isString(Object o) {
            return (o == null) ? true : String.class.isInstance(o);
        }
    
        /**
         * 1,3,6のどれか(またはnull)ならOKと判定します。
         */
        public static boolean validateTeiki(
            Object bean,
            ValidatorAction va,
            Field field,
            ActionMessage errors,
            HttpServletRequest request) {
    
            String value = null;
            if (isString(bean)) {
                value = (String) bean;
            } else {
                value = ValidatorUtil.getValueAsString(bean, field.getProperty());
            }
            if (value != null && !value.equals("1") && !value.equals("3") && !value.equals("6")) {
                errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
                return false;
            } else {
                return true;
            }
        }
    
        /**
         * 変数inに,で区切られた候補値のどれか(またはnull)ならOKと判定します。
         * 大文字・小文字は区別します。また,の前後に空白を挟むとそれも候補値の中に含まれます。
         * 変数inがnullまたは空白の場合、常にNGとなります。
         * 変数in内の候補自体に,を含めることはできません。
         */
        public static boolean validateIn(
            Object bean,
            ValidatorAction va,
            Field field,
            ActionMessage errors,
            HttpServletRequest request) {
    
            String value = null;
            if (isString(bean)) {
                value = (String) bean;
            } else {
                value = ValidatorUtil.getValueAsString(bean, field.getProperty());
            }
    
            String ins = field.getVarValue("in");
            if(value == null){
                return true;
            } else if(ins == null){
                errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
                return false;
            } else {
                StringTokenizer stok = new StringTokenizer(ins, ",");
                while(stok.hasMoreTokens()){
                    if (value.equals(stok.nextToken())){
                        return true;
                    }
                }
                errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
                return false;
            }
        }
    }
    

    引数は例に示した5つが基本ですが、 最後にjavax.servlet.ServletContextの引数を追加することもできるようです。
    上の例ではvalidateTeiki、validateInという2つの検証方法を定義しています。 前者は入力値が1,3,6のどれかならOK、後者は変数inにカンマ区切りで指定した候補値のうちどれかであればOK (例えばin変数の値が "M,F" ならば、"M"か"F"ならOK) というものです。但し前者は標準のmaskバリデータでも十分代用できますし、 後者は性別を想定したものですが普通キー入力ではなくドロップダウンで選ぶものなので、 どちらもあまり役立つものではないですね。あくまで例ということで…
  2. 次に/WEB-INF/validation.xmlに、これらのバリデータの定義を追加します。

    <form-validation>
      <global>
        <validator name="teiki"
             classname="shiten.struts.validator.ExampleValidator"
                method="validateTeiki"
          methodParams="java.lang.Object,
                        org.apache.commons.validator.ValidatorAction,
                        org.apache.commons.validator.Field,
                        org.apache.struts.action.ActionMessages,
                        javax.servlet.http.HttpServletRequest"
               depends=""
                   msg="errors.teiki" jsFunction="aaa">
        </validator>
    
        <validator name="in"
             classname="shiten.struts.validator.ExampleValidator"
                method="validateIn"
          methodParams="java.lang.Object,
                        org.apache.commons.validator.ValidatorAction,
                        org.apache.commons.validator.Field,
                        org.apache.struts.action.ActionMessages,
                        javax.servlet.http.HttpServletRequest"
               depends=""
                   msg="errors.in" jsFunction="aaa">
        </validator>
      </global>
    
      <formset>
    ...
    </form-validation>
    

    msgには、そのエラーが検出されたときに表示するエラーメッセージの、 メッセージ・リソースのキーを指定します。
  3. /WEB-INF/struts-config.xmlにアクションフォームBeanを定義します。

    <form-bean name="TeikiExampleForm" type="org.apache.struts.validator.DynaValidatorForm">
      <form-property name="kikan" type="java.lang.String" />
      <form-property name="seibetsu" type="java.lang.String" />
    </form-bean>
    

  4. 再び/WEB-INF/validation.xmlに戻って、 フォームアクションBeanに対する検証ルールを定義します。

    <formset>
      <form name="TeikiExampleForm">
        <field property="kikan" depends="teiki">
          <arg0 key="teiki.kikan.displayName"/>
        </field>
        <field property="seibetsu" depends="in">
          <arg0 key="teiki.seibetsu.displayName"/>
          <var>
            <var-name>in</var-name>
            <var-value>M,F</var-value>
          </var>
        </field>
      </form>
    </formset>
    

  5. ApplicationResources.propertiesに、エラーメッセージで使用するメッセージ・リソースを定義します。

    errors.teiki=<li>{0}の値は1,3,6のどれかでなくてはいけません。</li>
    errors.in=<li>{0}の値が不適正です。</li>
    teiki.kikan.displayName=定期期間
    teiki.seibetsu.displayName=性別
    

  6. 最後にJSPとアクションクラスを作成します。下は簡単な入力フォームのJSPです。

    <%@ page contentType="text/html;charset=Windows-31J" language="java" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    
    <html:html locale="true"><head><title>validatorのテスト(定期)</title><html:base/></head>
    <body bgcolor="white">
    <html:errors/>
    <html:form action="/TeikiExample" focus="kikan">
    期間(1,3,6):<html:text property="kikan" size="3" maxlength="1"/>
    性別(M or F):<html:text property="seibetsu" size="3" maxlength="1"/>
      <br>
      <html:submit value="検索"/>
    </table>
    </html:form>
    
    <html:img page="/struts-power.gif" alt="Powered by Struts"/>
    </body>
    </html:html>
    

Server Side Java Index Top

(first uploaded 2004/03/27 last updated 2006/02/22, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル