天天看点

Struts2 自定义验证器

前言

正题

1.工程目录结构图:

Struts2 自定义验证器

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>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    <welcome-file-list>

        <welcome-file>validatordate.jsp</welcome-file>

    </welcome-file-list>

</web-app>

    b).    struts.xml

<!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"

    <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>

    e).    validatoraction-validation.xml

<!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">

                <![cdata[ 不是一个有效的月份! ]]>

    <field name="regexdayfield">

            <!-- 是否使用正则表达式验证日期 -->

            <param name="isregex">false</param>

            <!-- 使用自定义正则表达式验证日期 -->

            <!-- 

                <param name="expression"></param>

            -->

                <![cdata[ 当前月份的天数不对! ]]>

</validators>

说明:验证文件需要和action在同一目录下, 验证文件命名规则:验证文件xxxx-validation.xml,这个xxxx就是你前面action的类名字,xxx-xxx-validation.xml第二个xxx表示是别名.

    f).    validators.xml

    <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"/>

说明:在源码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

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

    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 true;

说明:验证日期的正则表达式就是在网上找的,可以替换成自己的.

    i).    dateex

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;

            temp = integer.valueof(value);

        } catch (numberformatexception ex) {

            addfielderrorex(getfieldname(), object);

        if (temp != null) {

            if (temp >= minyear && temp <= maxyear)

                map.put("year", temp);

            else

                addfielderrorex(getfieldname(), object);

     * 验证月份

    private void validatemonth(string value, object object)

            integer temp = integer.valueof(value);

            if (temp != null) {

                if (temp >= 1 && temp <= 12)

                    map.put("month", temp);

                else

                    addfielderrorex(getfieldname(), object);

            }

     * 验证日期

    private void validateday(string value, object object)

                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();

     * 控制是否只显示一条报错信息

     * @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的文章.

转载:http://www.cnblogs.com/over140/archive/2007/12/04/982934.html