zoukankan      html  css  js  c++  java
  • 独自のバリデータ(Validator)を作ってみる

    SAStrutsでは独自バリデータも作れます。

    Strutsで作っていたものがある場合には、それを流用することもできます。

    今回は、あまりいいネタもなかったので、特定の数の倍数でないとエラーになるバリデータを作ってみました。

    アノテーションを作る

    まずは、アノテーションから作ります。

    アノテーションから作るのは、ここでバリデータの仕様がだいたい決まるからです。

    package sample.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.seasar.struts.annotation.Arg;
    import org.seasar.struts.annotation.Msg;
    import org.seasar.struts.annotation.Validator;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @Validator("afoCheck")
    public @interface AfoCheck {
        int baisu() default 3;
    
        Msg msg() default @Msg(key = "errors.afo");
    
        Arg arg0() default @Arg(key = "");
    
        Arg arg1() default @Arg(key = "${var:baisu}", resource = false);
    
        String target() default "";
    }
    

    デフォルトでは、3の倍数でない場合にはエラーとしますが、baisuに任意の値を入れることも可能です。

    エラーメッセージデフォルトは、msgアノテーションで指定します。

    arg0については、デフォルトではSAStrutsのものと同じ動きで、プロパティ名を出力します。国際化する場合には、labels.プロパティ名をメッセージソースに用意します。

    arg1は、デフォルトでは、baisuに設定した値を出力します。変えることも可能です(あまり意味はないですが)。

    targetは、バリデータでチェックするメソッド名をカンマ区切りで指定します。この辺もSAStrutsのほうで面倒を見てくれるので、上記のように記述しておく必要があります。

    ちなみに、@Retentionとか、@Targetアノテーションは、先日の日記(http://d.hatena.ne.jp/kuwalab/20080615#1213527631)を参照。

    チェックメソッド作成

    チェックメソッドは、org.seasar.struts.validator.S2FieldChecksクラス継承するのが楽です。

    今回は、以下のように書きました。

    package sample.util;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.commons.validator.Field;
    import org.apache.commons.validator.GenericValidator;
    import org.apache.commons.validator.Validator;
    import org.apache.commons.validator.ValidatorAction;
    import org.apache.struts.action.ActionMessages;
    import org.seasar.struts.validator.S2FieldChecks;
    
    public class AfoFieldChecks extends S2FieldChecks {
        private static final long serialVersionUID = 1L;
    
        public static boolean validateAfoCheck(Object bean, 
                ValidatorAction validatorAction,
                Field field, ActionMessages errors,
                Validator validator, HttpServletRequest request) {
            String value = getValueAsString(bean, field);
            if (!GenericValidator.isBlankOrNull(value)) {
                try {
                    int checkValue = Integer.parseInt(value);
                    int baisu = Integer.parseInt(field.getVarValue("baisu"));
                    if (checkValue % baisu != 0) {
                        addError(errors, field, validator, validatorAction, request);
                        return false;
                    }
                } catch (Exception e) {
                    addError(errors, field, validator, validatorAction, request);
                    return false;
                }
            }
            return true;
        }
    }
    

    ソースは簡単なので、解説の必要はあまりないかと思います。

    validator-rules.xml

    最後に、WEB-INF以下のvalidator-rules.xmlファイルに追記します。

    <validator name="afoCheck"
    classname="sample.util.AfoFieldChecks"
    method="validateAfoCheck"
    methodParams="java.lang.Object,
                     org.apache.commons.validator.ValidatorAction,
                     org.apache.commons.validator.Field,
                     org.apache.struts.action.ActionMessages,
                     org.apache.commons.validator.Validator,
                     javax.servlet.http.HttpServletRequest"
    depends=""
    msg="errors.afo"/>
    

    nameバリデータの名前、classnameにチェックするクラス、methodにクラスのメソッド名、msgにメッセージのキーを指定します。

    あとは、このチェックをする前にチェックする必要のあるバリデータがあれば、dependsに指定します。(longRangeのチェックの場合には、longとかを指定している。)

    メッセージソース

    メッセージと、プロパティを国際化する場合に記述します。

    今回は以下のようにしています。

    errors.afo={0}は{1}の倍数でなければ、アフォになります。
    labels.afo1=項目「アフォ1」
    

    使ってみる

    最後にActionで使ってみます。

    まずは、JSP

    index.jspとしています。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"lang="ja">
     <head>
      <title>アフォチェック</title>
     </head>
     <body>
      <html:errors/>
      <s:form>
     好きな数字を入れてよ <html:text property="afo1"size="10"maxlength="10" /><br />
     好きな数字を入れてよ <html:text property="afo2"size="10"maxlength="10" /><br />
       <inputtype="submit"name="afoCheck1"value="1と2"/>
       <inputtype="submit"name="afoCheck2"value="1"/>
       <inputtype="submit"name="afoCheck3"value="2"/>
      </s:form>
     </body>
    </html>
    

    そして、Action。

    package sample.action;
    
    import org.seasar.struts.annotation.Execute;
    
    import sample.annotation.AfoCheck;
    
    public class AfoAction {
        @AfoCheck(target = "afoCheck1, afoCheck2")
        public String afo1;
    
        @AfoCheck(baisu = 4, target = "afoCheck1, afoCheck3")
        public String afo2;
    
        @Execute(validator = false)
        public String index() {
            return "index.jsp";
        }
    
        @Execute(input = "index.jsp")
        public String afoCheck1() {
            return "index.jsp";
        }
    
        @Execute(input = "index.jsp")
        public String afoCheck2() {
            return "index.jsp";
        }
    
        @Execute(input = "index.jsp")
        public String afoCheck3() {
            return "index.jsp";
        }
    }
    

    動かしてみる

    無事、アフォになりました。

    感想

    思ったより簡単にできました。

    バリデータをXMLで書いていた頃を思うと、アノテーションでエラーチェックができるのはなんて簡単だろうと思います。

    Strutsで独自バリデータを作っている人はかなりいる(と思う)ので、SAStrutsでもちょっとアノテーションを作成するだけで、資産を流用できるのはいいと思います。

  • 相关阅读:
    window计时器函数
    日期函数
    字符的方法
    五大主流浏览器与四大内核
    向一个排好序的数组中插入一个数组。
    冒泡与排序
    数组去重方法1,2,3
    有执行语句:console.log(fn2(2)[3]),补充函数,使执行结果为"hello"
    面试题:一个函数的调用 fn(2)(3)(4) 得到的结果位24; 这个函数是柯里化函数运用了闭包原理
    python中append()与extend()方法的区别
  • 原文地址:https://www.cnblogs.com/aggavara/p/2716367.html
Copyright © 2011-2022 走看看