• Struts2 自定义验证器



    前言

        其实早在四月底就在JR上发表了这篇文章,这次再次搬出来一是为了资料集中,二是做一些修改和更详细的描述.和以往一样入门和介绍就不说了,如何学习在上篇文章Struts2+JFreeChart上有介绍.


    正题
    1.工程目录结构图:

    2.以下依次帖代码:
        a).    web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation
    ="http://java.sun.com/xml/ns/j2ee 
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    >
        
    <filter>
            
    <filter-name>struts2</filter-name>
            
    <filter-class>
                org.apache.struts2.dispatcher.FilterDispatcher
            
    </filter-class>
        
    </filter>
        
    <filter-mapping>
            
    <filter-name>struts2</filter-name>
            
    <url-pattern>/*</url-pattern>
        
    </filter-mapping>

        
    <welcome-file-list>
            
    <welcome-file>ValidatorDate.jsp</welcome-file>
        
    </welcome-file-list>
    </web-app>
        b).    struts.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC 
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
        "http://struts.apache.org/dtds/struts-2.0.dtd"
    >

    <struts>
        
    <include file="struts-validation.xml" />
    </struts>
        c).    struts.properties
    struts.ui.theme=simple
        d).    struts-validation.xml
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd"
    >

    <struts>

        
    <package name="validationExamples" extends="struts-default"
            namespace
    ="/validation">
            
    <action name="ValidatorField"
                class
    ="com.tangjun.validator.ValidatorAction">
                
    <!-- 这里input表示验证失败后指定跳转到什么地方去 -->
                
    <result name="input" type="dispatcher">/ValidatorDate.jsp</result>
                
    <result>/success.jsp</result>
            
    </action>
        
    </package>
    </struts>
        e).    ValidatorAction-validation.xml
    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE validators PUBLIC 
              "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
              "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"
    >
    <validators>
        
    <field name="regexYearField">
            
    <field-validator type="mydate">
                
    <param name="maxYear">2008</param>
                
    <param name="minYear">1900</param>
                
    <message>
                    
    <![CDATA[ 不是一个有效的年份! ]]>
                
    </message>
            
    </field-validator>
        
    </field>
        
    <field name="regexMonthField">
            
    <field-validator type="mydate">
                
    <message>
                    
    <![CDATA[ 不是一个有效的月份! ]]>
                
    </message>
            
    </field-validator>
        
    </field>
        
    <field name="regexDayField">
            
    <field-validator type="mydate">
                
    <!-- 是否使用正则表达式验证日期 -->
                
    <param name="isRegex">false</param>
                
    <!-- 使用自定义正则表达式验证日期 -->
                
    <!-- 
                    <param name="expression"></param>
                
    -->
                
    <message>
                    
    <![CDATA[ 当前月份的天数不对! ]]>
                
    </message>
            
    </field-validator>
        
    </field>

    </validators>

    说明:验证文件需要和Action在同一目录下, 验证文件命名规则:验证文件xxxx-validation.xml,这个xxxx就是你前面action的类名字,xxx-xxx-validation.xml第二个xxx表示是别名.
        f).    validators.xml
    <validators>
        
    <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
        
    <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
        
    <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
        
    <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
        
    <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
        
    <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
        
    <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
        
    <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
        
    <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
        
    <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
        
    <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
        
    <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
        
    <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
        
    <validator name="mydate" class="com.tangjun.validator.DateEx"/>
    </validators>
    说明:在源码com.opensymphony.xwork2.validator.ValidatorFactory中,在325行至330那一段代码可以看出,如果不能在根目录下找到validators.xml文件,验证框架将调用默认的验证设置,即com.opensymphony.xwork2.
    validator.validators目录下default.xml里面的配置信息.最后一个<validator name="mydate" class="com.tangjun.validator.DateEx"/>就是我添加的默认验证器类型.
        g).    ValidatorAction
    package com.tangjun.validator;

    import com.opensymphony.xwork2.ActionSupport;

    /**
     * 验证日期
     * 
     * 
    @author lzl
     * 
     
    */
    public class ValidatorAction extends ActionSupport {

        
    private static final long serialVersionUID = -4829381083003175423L;

        
    private Integer regexYearField;

        
    private Integer regexMonthField;

        
    private Integer regexDayField;

        
    public ValidatorAction()
        {
            regexYearField 
    = null;
            regexMonthField 
    = null;
            regexDayField 
    = null;
        }
        
        @Override
        
    public String execute() throws Exception {
            
    return SUCCESS;
        }

        
    public Integer getRegexDayField() {
            
    return regexDayField;
        }

        
    public void setRegexDayField(Integer regexDayField) {
            
    this.regexDayField = regexDayField;
        }

        
    public Integer getRegexMonthField() {
            
    return regexMonthField;
        }

        
    public void setRegexMonthField(Integer regexMonthField) {
            
    this.regexMonthField = regexMonthField;
        }

        
    public Integer getRegexYearField() {
            
    return regexYearField;
        }

        
    public void setRegexYearField(Integer regexYearField) {
            
    this.regexYearField = regexYearField;
        }

    }
        h).    BeanUtils
    package com.tangjun.validator;

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class BeanUtils {

        
    /* 默认验证日期正则表达式 */
        
    private static final String DateExpression = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)";

        
    /**
         * 验证日期合法性(通过抛出错误方式来验证)
         * 
    @param date
         * 
    @return
         
    */
        
    public static boolean validatorDate(String date) {
            
    // 注意这个地方"yyyy-MM-dd"如果设置成了yyyy-mm-dd的话验证将失灵
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            
    // 这个的功能是不让系统自动转换 不把1996-13-3 转换为1997-3-1
            sdf.setLenient(false);
            
    try {
                sdf.parse(date);
                
    return true;
            } 
    catch (ParseException e) {
                
    return false;
            }
        }

        
    /**
         * 使用正则表达式判定日期
         * 
         * 
    @param str
         * 
    @param expression
         * 
    @return
         
    */
        
    public static boolean regexValidatorDate(String str, String expression) {
            
    // 使用正则表达式进行判定
            if (expression == null || expression.trim().length() == 0)
                expression 
    = BeanUtils.DateExpression;
            Pattern pattern;
            
    // System.out.println(expression);
            pattern = Pattern.compile(expression, 2);
            Matcher matcher 
    = pattern.matcher(str.trim());
            
    if (!matcher.matches()) {
                
    return false;
            }
            
    return true;
        }
    }
    说明:验证日期的正则表达式就是在网上找的,可以替换成自己的.
        i).    DateEx
    package com.tangjun.validator;

    import java.util.HashMap;

    import com.opensymphony.xwork2.validator.ValidationException;
    import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

    public class DateEx extends FieldValidatorSupport {

        
    private static HashMap<String, Integer> map = new HashMap<String, Integer>();

        
    /* 默认最大年限 */
        
    private static final Integer MAX_YEAR = 2008;

        
    /* 默认最小年限 */
        
    private static final Integer MIN_YEAR = 1900;

        
    /* 最大年限 */
        
    private Integer maxYear;

        
    /* 最小年限 */
        
    private Integer minYear;

        
    /* 验证日期的正则表达式 */
        
    private String expression;

        
    /* 是否使用正则表达式验证 */
        
    private Boolean isRegex;
        
        
    public DateEx() {
            maxYear 
    = null;
            minYear 
    = null;
            expression 
    = null;
            isRegex 
    = false;
        }

        
    public void validate(Object object) throws ValidationException {

            
    // 获得字段的名字
            String fieldName = getFieldName();
            
    // 获得输入界面输入的值
            String value = getFieldValue(fieldName, object).toString();

            
    if (value == null || value.length() <= 0)
                
    return;

            
    if (fieldName.equals("regexYearField"))
                validateYear(value, object);
            
    else if (fieldName.equals("regexMonthField"))
                validateMonth(value, object);
            
    else if (fieldName.equals("regexDayField"))
                validateDay(value, object);
        }

        
    /**
         * 验证年份
         * 
         * 
    @param object
         * 
    @throws ValidationException
         
    */
        
    private void validateYear(String value, Object object)
                
    throws ValidationException {
            
    /* 设置默认值 */
            
    if (maxYear == null) {
                maxYear 
    = MAX_YEAR;
            }
            
    if (minYear == null) {
                minYear 
    = MIN_YEAR;
            }

            Integer temp 
    = null;
            
    try {
                temp 
    = Integer.valueOf(value);
            } 
    catch (NumberFormatException ex) {
                addFieldErrorEx(getFieldName(), object);
                
    return;
            }

            
    if (temp != null) {
                
    if (temp >= minYear && temp <= maxYear)
                    map.put(
    "year", temp);
                
    else
                    addFieldErrorEx(getFieldName(), object);
            }
        }

        
    /**
         * 验证月份
         * 
         * 
    @param object
         * 
    @throws ValidationException
         
    */
        
    private void validateMonth(String value, Object object)
                
    throws ValidationException {
            
    try {
                Integer temp 
    = Integer.valueOf(value);
                
    if (temp != null) {
                    
    if (temp >= 1 && temp <= 12)
                        map.put(
    "month", temp);
                    
    else
                        addFieldErrorEx(getFieldName(), object);
                }
            } 
    catch (NumberFormatException ex) {
                addFieldErrorEx(getFieldName(), object);
                
    return;
            }
        }

        
    /**
         * 验证日期
         * 
         * 
    @param object
         * 
    @throws ValidationException
         
    */
        
    private void validateDay(String value, Object object)
                
    throws ValidationException {
            
    try {
                Integer temp 
    = Integer.valueOf(value);
                
    if (temp != null) {
                    Integer year 
    = map.get("year");
                    Integer month 
    = map.get("month");
                    
                    
    //直接使用天数
                    if(year==null || month==null)
                    {
                        
    return;
                    }
                    
                    
    // 是否使用正则表达式验证
                    if (!isRegex) {
                        
    if(!BeanUtils.validatorDate(year + "-" + month + "-" + temp))
                            addFieldErrorEx(getFieldName(), object);
                    } 
    else {
                        String StrDay 
    = temp < 10 ? "0" + temp.toString() : temp
                                .toString();

                        String StrMonth 
    = month < 10 ? "0" + month.toString()
                                : month.toString();

                        
    //前面已经验证过了
                        
    //String StrYear = year < 100 ? year < 10 ? "200" + year: "19" + year : "1" + year;

                        String str 
    = year + "-" + StrMonth + "-" + StrDay;

                        System.out.println(
    "Date:" + str);

                        
    if (expression == null) {
                            
    if(!BeanUtils.regexValidatorDate(str, null))
                                addFieldErrorEx(getFieldName(), object);
                        } 
    else {
                            
    if (expression.trim().length() > 0) {
                                
    if(BeanUtils.regexValidatorDate(str, expression))
                                    addFieldErrorEx(getFieldName(), object);
                            }
                        }
                    }
                    map.clear();
                }
            } 
    catch (NumberFormatException ex) {
                addFieldErrorEx(getFieldName(), object);
                
    return;
            }
        }

        
    /**
         * 控制是否只显示一条报错信息
         * 
         * 
    @param arg0
         * 
    @param arg1
         
    */
        
    private void addFieldErrorEx(String arg0, Object arg1) {
            
    //if (this.getValidatorContext().getFieldErrors().size() == 0)
                addFieldError(arg0, arg1);
        }

        
    public Integer getMaxYear() {
            
    return maxYear;
        }

        
    public void setMaxYear(Integer maxYear) {
            
    this.maxYear = maxYear;
        }

        
    public Integer getMinYear() {
            
    return minYear;
        }

        
    public void setMinYear(Integer minYear) {
            
    this.minYear = minYear;
        }

        
    public String getExpression() {
            
    return expression;
        }

        
    public void setExpression(String expression) {
            
    this.expression = expression;
        }

        
    public Boolean getIsRegex() {
            
    return isRegex;
        }

        
    public void setIsRegex(Boolean isRegex) {
            
    this.isRegex = isRegex;
        }
    }
    说明:在DateEx里面,这个时候你就可以参照如IntRangeFieldValidator(反编译源码)等他实现的验证器来写自己的验证器了。这里注意了,你在这个类里面每写一个属性(含get set方法),就对应的一个xxxx-validation.xml这个配置文件里面<param name="expression"></param>这个name的名字了,可以在扩展类里面直接获得了,根据传入参数进行自定义方式验证了。如下object是validate传进来的参数,表示你输入的数据对象:
    // 获得字段的名字
    String fieldName = getFieldName();
    // 获得输入界面输入的值
    String value = getFieldValue(fieldName, object).toString();

    总结
    验证器是拦截器即Interceptor实现的,所以并没有看见任何代码把他们和我的action文件关联起来,他们默认的验证了,这方面可以参考Max On Java的文章.

  • 相关阅读:
    Linux 系统中 sudo 命令的 10 个技巧
    如何在 Linux 中配置基于密钥认证的 SSH
    选择 NoSQL 数据库需要考虑的 10 个问题
    10 个 Linux 中方便的 Bash 别名
    扒一扒 EventServiceProvider 源代码
    [Binary Hacking] ABI and EABI
    瀑布流 ajax 预载入 json
    PHP5+标准函数库观察者之实现
    使用汇编分析c代码的内存分布
    but no declaration can be found for element &#39;aop:aspectj-autoproxy&#39;.
  • 原文地址:https://www.cnblogs.com/over140/p/982934.html
Copyright © 2020-2023  润新知