首页 > 代码库 > Struts2之数据校验

Struts2之数据校验

 

时间:2017-1-11 11:09

 

——Struts2提供的数据校验

在开发中,请求参数是需要校验的:
    客户端:过滤正常用户的错误操作,通过JS代码完成
    服务器:Java代码

Struts2提供的校验是服务器端校验。

校验方式分为两种:
    1、手动校验(编码校验)
    2、配置校验(自动校验,基于Annotation,基于XML)

1、手动校验:
    要求:Action类必须继承ActionSupport,需要重写validate()方法(是Validateable接口中的一个方法)

    通过测试发现在Action中重写的validate()方法执行了,并且是在请求处理方法execute()方法之前执行的。

    对于Struts2提供的校验,也是通过拦截器实现的:

        技术分享

    问题:如何在validate()方法中存储校验错误信息?
        在validate()方法中:this.addFieldError(String name, String value)
        当集合不为空时,转向错误页面。

    问题:如何在页面上获取错误信息(在input视图中)?
        导入标签库:<%@ taglib prefix="s" uri="/struts-tags" %>
        使用标签:
            展示所有错误信息:<s:fielderror/>
            展示特定的错误信息:<s:fielderror fieldName="name"> name是this.addFieldError()方法中保存的name值。

    问题:在同一个Action中存在多个请求处理方法(regist()、login()),有些方法是需要校验的,有些方法是不需要校验的,如何处理?
        定义一个名称为:validate+请求处理方法名。
        例如:请求处理方法:regist,那么校验的方法名就是:validateRegist(),只针对regist请求方法进行校验。
        validateRegist(){ ... }:请求regist()方法时会被调用,而请求login()方法时不会被调用。
        不是通过配置文件也不是通过注解,而是通过一种“约定规范”来起名的。

        当同时存在validateRegist()方法和validate()方法时,会先执行validateRegist()再执行validate(),可以将一些公共校验放到validate()方法中。

    示例代码:

        public class UserAction extends ActionSupport implements ModelDriven {
            private User user = new User();
 
            public Object getModel() {
                return this.user;
            }

            public void validateRegist() { 
                ....
            } 
 
            @Override
            public void validate() {
                System.out.println("validate...");
                if (user.getUsername() == null || user.getUsername().trim().length() == 0) {
                    // 说明用户名为空
                    this.addFieldError("username.meeage", "用户名不能为空");
                }
 
                if (user.getPassword() == null || user.getPassword().trim().length() == 0) {
                    // 密码为空
                    this.addFieldError("password.message", "密码不能为空");
                }
            }
        }

    手动校验的流程
        1)类型转换器对请求参数执行类型转换,并把转换后的值赋给Action中的属性。
        2)如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext中,conversionError拦截器将异常信息封装到fieldErrors中,然后执第3步,如果没有出现类型转换异常,则直接进入第3步。

        3)系统通过反射调用Action中的validateXxx()方法,Xxx为方法名。
        4)调用Action中的validate()方法。
        5)经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统将自动请求转发至input视图,如果系统中的fieldErrors没有任何错误信息,系统将执行Action中的处理方法。




2、配置校验(XML格式)
    也叫作Struts2的校验框架,Struts2框架已经完成了校验操作(完成了很多校验方法),而我们在使用时,只需要将它们调用就可以了。(需要通过配置文件)

    配置校验器之后,Action中不需要再写validate()方法了。

    要求:Action类必须继承ActionSupport类

    问题:配置文件怎样配置?
        1)配置文件的位置
            *   XML文件要与Action类在同一个包下
        2)配置文件的名称
            *   Action类名-validation.xml
        3)配置文件的约束
            *   在xwork-core-2.3.15.1.jar包下的xwork-validator-1.0.3.dtd约束文件中查找

            *   <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

        4)配置文件的书写
            *   根元素:<validators>
                >   子元素:<field>(单值校验)
                    <field name="属性名称"></field>,指定Action中要校验的属性,name属性指定将被验证的表单字段的名字。
                    驱动模型属性下依然只写属性名,不写对象名。
                    >   子元素:<field-validator type="校验器"></fieldvalidator>
                        指定校验器,type表示指定验证规则。
                        >   子元素:<message>用户名不能为空</message>
                            用于定义错误信息
                        >   子元素:<param name="">值</param>:
                            用于指定校验器参数(属性)的。

    问题:校验器有哪些?
        在这个路径中查找:/com/opensymphony/xwork2/validator/validators/default.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="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
            <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
            <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="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
        </validators>


        *   required:必填校验器,要求被校验的属性值不能为null。
        *   requiredstring:必填校验器,要求被校验的属性值不能为null,并且长度大于0,默认情况下会去除字符串前后空格。
            >   在reqyuredstring所对应的类中,trim默认为true,如果想要修改其值,可以在校验器下添加子元素:<param name="trim">false</param>
            >   public class RequiredStringValidator extends FieldValidatorSupport {

                     private boolean trim = true;
                     ......
                 } 

        *   stringlength:字符串长度校验器要求被校验的属性值长度必须在指定范围内,否则校验失败,minLength参数指定最小长度,maxLength参数指定最大长度,trim参数指定校验field之前是否去除字符串前后空格。
        *   regex:正则表达式校验器,检查被校验的属性值是否匹配一个正则表达式,expression参数指定正则表达式,caseSensitive参数指定进行正则表达式匹配时,是否区分大小写,默认为true。
        *   int:整数校验器,要求field的整数值必须在指定范围内,min指定最小值,max指定最大值。
        *   double:双精度浮点数校验器,要求field的双精度浮点数必须在指定范围内,main指定最小值,max指定最大值。
        *   fieldexpression:字段OGNL表达式校验器,要求field满足一个OGNL表达式,expression参数指定OGNL表达式与该逻辑表达式基于ValueStack进行求值,返回true时校验通过,否则失败。
        *   email:邮件地址校验器,要求如果被校验的属性值为非空,必须是合法的邮件地址。
        *   url:网址校验器,要求如果被校验的属性值非空,必须是合法的url地址。
        *   date:日期校验器,不是校验日期格式,而是要求field的日期值必须在指定范围内,min指定最小值,max指定最大值。


    示例代码:

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
 
        <validators>
            <!-- 对username属性进行校验 -->
            <field name="username">
                <!-- 指定username不能为空 -->
                <field-validator type="requiredstring">
                    <!-- 设置错误信息 -->
                    <message>用户名不能为空2</message>
                </field-validator>
 
                <!-- 长度校验,规定用户名必须在6-10位之间 -->
                <field-validator type="stringlength">
                    <!-- maxLength、minLength是stringlength对应类中的属性 -->
                    <param name="maxLength">10</param>
                    <param name="minLength">6</param>
                    <!-- 想获取属性值,可以使用ognl表达式 -->
                    <message>用户名必须在${minLength}-${maxLength}位之间</message>
                </field-validator>
            </field>
 
            <!-- 对age进行校验 -->
            <field name="age">
                <!-- 规定age必须在10-40之间 -->
                <field-validator type="int">
                    <param name="min">10</param>
                    <param name="max">40</param>
                    <message>年龄必须在${min}-${max}之间</message>
                </field-validator>
            </field>
 
            <!-- 对birthday进行校验 -->
            <field name="birthday">
                <field-validator type="date">
                    <param name="max">2000-1-1</param>
                    <param name="min">1000-1-1</param>
                    <message>生日必须在${min}-${max}之间</message>
                </field-validator>
            </field>
 
            <!-- 校验邮箱格式 -->
            <field name="email">
                <field-validator type="email">
                    <message>邮箱格式不正确</message>
                </field-validator>
            </field>
 
            <!-- url格式校验,要求是一个正确的url网络路径 -->
    <field name="url">
                <field-validator type="url">
                    <message>url格式不正确</message>
                </field-validator>
            </field>
 
            <!-- 使用正则表达式验证tel -->
            <field name="tel">
                <field-validator type="regex">
                    <!-- 188开头,长度11位 -->
                    <!-- 在对应类中有regexExpression属性 -->
                    <!-- CDATA表示该区域字符串不会被解析 -->
                    <param name="regexExpression"><![CDATA[^188[0-9]{8}$]]></param>
                    <message>电话号码必须是188开头,长度11位</message>
                </field-validator>
            </field>
 
            <!-- 判断密码是否一致 -->
            <field name="repassword">
                <field-validator type="fieldexpression">
                    <param name="expression"><![CDATA[(password==repassword)]]></param>
                    <message>密码不一致</message>
                </field-validator>
            </field>
        </validators>




    问题:通过配置校验,怎样处理在同一个Action中存在多个请求处理方法校验问题?
        有多个方法,其中某些方法不需要校验,如何实现?
        只需要将校验XML文件名称修改即可:
            针对Action的校验配置文件:Action类名-validation.xml
            现在只希望对Action类中某一个方法进行校验:
                Action类名-action名称(action的name属性)-validation.xml



        当Action提供了ActionClassName-validation.xml和ActionClassName-ActionName-validation.xml两种规则的校验文件时,系统会按照以下顺序查找校验文件:
        1)ActionClassName-validation.xml
        2)ActionClassName-ActionName-validation.xml

        先找大的,再找小的。
    系统查找到第一个校验文件时还会继续搜索后面的校验文件,当搜索到所有校验文件时,会把校验文件里的所有校验规则汇总,然后全部用于处理方法的校验,如果两个校验文件中指定的校验规则冲突,则以后面的文件中的校验规则为准。



    当Action继承了另一个Action,父类Action的校验文件会先被搜索到,假设UserAction继承了BaseAction,UserAction在struts.xml中的配置如下:
        <action name="user" class="com.wyc.action.UserAction" method="execute">
            ......
        </action>
    访问上面名为User的Action,系统先搜索到BaseAction-validation.xml,BaseAction-user-validation.xml,然后搜索到UserAction-validation.xml,UserAction-user-validation.xml,校验规则是这四个文件的总和。


    编写校验文件时,不能出现提示信息:
        在编写ActionClassName-validation.xml校验文件时,如果出现不了帮助信息,可以按下面方式解决:
windwos->preferences->myeclipse->files and editors->xml->xmlcatalog点“add”,在出现的窗口中的location中选“File system”,然后在xwork-2.1.2解压目录的src\java目录中选择xwork-validator-1.0.3.dtd,回到设置窗口的时候不要急着关闭窗口,应把窗口中的Key Type改为URI 。Key改为http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd
 


3、自定义校验规则(了解)
    步骤一:自定义校验器,必须实现Validator接口
        通常自定义校验器继承ValidatorSupport和FieldValidatorSupport
        *   ValidatorSipport针对不是一个的输入字段(比如比较两个密码是否相同)
        *   FieldValidatorSupport针对一个输入字段(比如判断用户名是否为空)

    步骤二:
        在工程的srx下创建validators.xml文件
        引入xword-core-2.3.7.jar中的xword-validator-config-1.0.dtd

    步骤三:使用校验器
        在Action所有包中创建:Action类名-validation.xml

    实际开发中很少用到自定义校验器。

——总结

1、Struts2请求参数校验
    *   手动编码校验(了解)
        >   Action继承ActionSupport类
        >   重写validate()方法
        >   使用addFieldError(String name, String msg)添加错误信息
        >   在页面中使用<s:fielderror>展示错误信息
    *   XML的配置校验
        >   位置:与Action类在同一包下
        >   名称:ActionClassName-validation.xml
        >   约束:在xwork-core包中的约束文件中查找
        >   书写:校验器在xwork-core包中的validator-validators包中的default.xml文件中查找

    *   校验器的介绍

 

Struts2之数据校验