zoukankan      html  css  js  c++  java
  • Struts2的输入验证(三)-短路验证与非字段验证

    一、短路验证

    若对一个字段使用多个验证器,默认情况下会执行所有的验证。若希望前面的验证器验证没有通过,后面的就不再验证,可以使用短路验证。

    1)同一个字段内的多个验证器,如果一个短路验证器验证失败,其他验证器不会继续校验

    2)验证程序配置文件中<validator  …/> 元素和 <field-validator  …/> 元素可以指定一个可选的 short-circuit 属性,该属性指定该验证器是否是短验证器,默认值为 false。

    1、示例:短路验证器

    要求:为age字段配置两个验证器:conversion类型转换验证器和int整数验证器,并将conversion配置为一个短路验证器。

    1)JSP页面代码、Action类的代码以及struts.xml的配置与“Struts2的输入验证(一)”中的相同;

    2)验证配置文件TestValidationAction-testValidation-validation.xml中段的配置内容为:

    <!-- 针对 age 属性进行验证. 基于字段的验证 -->
    <field name="age">    
        <!-- 设置短路验证: 若当前验证没有通过, 则不再进行下面的验证 -->
        <field-validator type="conversion" short-circuit="true">
            <message>Conversion Error Occurred</message>
        </field-validator>
        <field-validator type="int">
            <param name="min">20</param>
            <param name="max">60</param>
            <message key="error.int"></message>
        </field-validator>
    </field>

    在Tomcat中部署运行后的结果如下图:

    结果1:视频教程中conversion校验器未设置short-circuit="true"时的结果(其中第一条是类型转换错误的信息,第二条是类型转换校验器的信息,第三条是整形校验器的信息)

    结果2:视频教程中conversion校验器设置了short-circuit="true"时的结果(这时,由于类型转换校验器校验未通过,因此没有再执行整形校验器)

     结果3:自己测试的结果(在自己进行测试时发现,在conversion校验器与int校验器配合使用时,无论是否设置conversion校验器的short-circuit属性为true,当输入内容不是一个整数时,都不会有int校验器的提示信息。经过Debug发现,当输入内容不是一个整数时,int校验器执行时,其获得的value值始终为null,因此其就直接返回了一个null,而不再进行校验,也没有添加校验失败的信息。不知道视频中是如何做的,用的都是同样的代码啊。???)

    总之,短路验证器的基本使用方法就同示例中一样,具体使用时在参考Struts2的官方文档了。

    2、存在的问题

    若类型转换失败,默认情况下还会执行后面的拦截器,还会进行验证(在Struts2默认的拦截器栈中,params拦截器在validate拦截器之前)。可以通过修改 ConversionErrorInterceptor 拦截器源代码的方式,使当类型转换失败时不再执行后续的验证拦截器,而直接返回 input 的 result。

    方法即在ConversionErrorInterceptor拦截器的intercept()方法return之前添加如下代码:

    1 Object action = invocation.getAction();
    2 if (action instanceof ValidationAware) {
    3     ValidationAware va = (ValidationAware) action;
    4     if(va.hasFieldErrors() || va.hasActionErrors()){
    5         return "input";
    6     }
    7 }

    即判断fielErrors与actionErrors中是否有值,如果有的话就说明有类型转换错误的信息,就直接返回不在执行后续的拦截器了。

    二、非字段验证

    即不是针对于某一个字段的验证。

    1、示例:非字段验证

    要求:校验两次输入的密码是否相同。

    1)JSP页面主要代码:

    1 <s:debug></s:debug>    
    2 <s:actionerror/> <%--注意:由于非字段校验不是针对于某个字段的校验,因此其错误消息不是fieldError类型的,而是actionError类型的,因此要使用actionerror标签来显示--%>
    3 <s:form action="testValidation" theme="simple">
    4     Password: <s:password name="password"></s:password><br>
    5     Password2: <s:password name="password2"></s:password><br>
    6     <s:submit></s:submit>
    7 </s:form>

    2)Action类的代码:

     1 package com.atguigu.struts2.validation.app;
     2 import com.opensymphony.xwork2.ActionSupport;
     3 public class TestValidationAction extends ActionSupport {
     4     private String password;
     5     private String password2;
     6     public String getPassword() {
     7         return password;
     8     }
     9     public void setPassword(String password) {
    10         this.password = password;
    11     }
    12     public String getPassword2() {
    13         return password2;
    14     }
    15     public void setPassword2(String password2) {
    16         this.password2 = password2;
    17     }
    18     public String execute() throws Exception {
    19         System.out.println("password: " + password);
    20         System.out.println("password2: " + password2);
    21         return SUCCESS;
    22     }
    23 }

    3)struts.xml文件的基本配置:

    <action name="testValidation" class="com.atguigu.struts2.validation.app.TestValidationAction">
        <result>/success.jsp</result>
        <!-- 若验证失败转向的 input -->
        <result name="input">/validation.jsp</result>
    </action>

    4)验证程序的配置文件,文件名为:TestValidationAction-validation.xml,配置内容:

    <validators>
        <!-- 测试非字段验证-->
        <validator type="expression">
            <param name="expression"><![CDATA[password==password2]]></param><!--注意:这里的表达式要写到CDATA区域(<![CDATA[……..]]>)中,因为其中可能有特殊字符-->
            <message>Password is not equals to password2</message>
        </validator>
    </validators>

    在Tomcat中部署并运行后,当两次输入的密码不相同时,运行结果如下图:

    注意:显示非字段验证的错误消息,使用 s:actionerror 标签:  <s:actionerror/>

    2、字段验证 VS 非字段验证

    1)字段验证字段优先,可以为一个字段配置多个验证规则。

    2)非字段验证验证规则优先。

    3)大部分验证规则支持两种验证器,但个别的验证规则只能使用非字段验证,例如表达式验证。 

    三、错误消息的重用性

    问题:多个字段使用同样的验证规则,可否使用同一条验证消息 ?

    1、示例:

    要求:页面上有age和count两个字段,这两个字段都是用int验证规则,要求当验证失败时,两者分别显示各自的错误消息。

    1)JSP页面的代码:

    1 <s:form action="testValidation" theme="simple">
    2     Age: <s:textfield name="age" label="Age"></s:textfield>
    3     ${fieldErrors.age[0] } <br>
    4     Count: <s:textfield name="count"></s:textfield>
    5     <s:fielderror fieldName="count"></s:fielderror>
    6     <br>
    7     <s:submit></s:submit>
    8 </s:form>

    2)Action类的代码:

     1 package com.atguigu.struts2.validation.app;
     2 import com.opensymphony.xwork2.ActionSupport;
     3 public class TestValidationAction extends ActionSupport {
     4     private Integer age;
     5     private Integer count;
     6     public Integer getAge() {
     7         return age;
     8     }
     9     public void setAge(Integer age) {
    10         this.age = age;
    11     }
    12     public Integer getCount() {
    13         return count;
    14     }
    15     public void setCount(Integer count) {
    16         this.count = count;
    17     }
    18     public String execute() throws Exception {
    19         System.out.println("age: " + age);
    20         System.out.println("count: " + count);
    21         return SUCCESS;
    22     }
    23 }

    3)struts.xml配置文件的内容同短路验证示例。

    4)验证程序的配置文件,文件名为:TestValidationAction-validation.xml,配置内容:

     1 <validators>
     2     <field name="age">
     3         <field-validator type="int">
     4             <param name="min">20</param>
     5             <param name="max">60</param>
     6             <message key="error.int"></message>
     7         </field-validator>
     8     </field>
     9     <field name="count">
    10         <field-validator type="int">
    11             <param name="min">1</param>
    12             <param name="max">10</param>
    13             <message key="error.int"></message>
    14         </field-validator>
    15     </field>
    16 </validators>

    5)添加国际化资源文件i18n.properties,并在其中添加如下内容:

    error.int=${getText(fieldName)} needs to be between ${min} and ${max}
    
    age=u5E74u9F84 注:这里是年龄
    count=u6570u91CF 注:这里是数量

    在Tomcat中部署并运行结果如下图,注意:这时验证失败消息中分别显示出了age与count字段在国际化资源文件中对应的名称“年龄”与“数量”:

    二、配置文件与验证器属性对应关系图解

  • 相关阅读:
    什么样的项目适合docker部署,docker应用场景
    算法学习导图+经典排序算法PHP实现
    Xmind激活:亲测有效
    小细节1:mysql数据库中的主键删除后出现自定义主键约束
    java笔试题:找出3~999的水仙花数的三种实现方式
    java笔试题:利用冒泡排序算法找出int类型数组当中最大的数字
    java笔试题:判断一个3~100之间的所有的素数?
    java笔试题:随机生成一个4位数字的年号,判断是否是闰年?
    java笔试题:判断一个小写字母是元音字母还是辅音字母?
    安装Maven方法
  • 原文地址:https://www.cnblogs.com/KnightKitt/p/3929849.html
Copyright © 2011-2022 走看看