手动完成输入校验

基于Struts 2校验器的校验可以完成绝大部分输入校验,但这些校验器都具有固定的校验逻辑,无法满足一些特殊的校验规则。对于一些特殊的校验要求,可能需要在Struts 2中进行手动校验。Struts 2提供了良好的可扩展性,从而允许通过手动方式完成自定义校验。

1.重写validate()方法

本应用一样采用前面的注册页面,但现在我们要求name请求参数的值必须包含crazyit字符串(这个要求其实也可通过正则表达式校验器完成,此处仅仅是示范)。现在我们通过重写ActionSupport类的validate()方法来进行这种校验。

下面的示例将对上面的注册应用进行改进,为上面的Web应用增加Struts 2支持。增加Struts 2支持后,将通过如下的Action来处理用户请求。下面的Action仅仅重写了ActionSupport类的validate方法。

下面是重写validate()方法后的RegistAction代码。

程序清单:codes\04\4.2\overrideValidate\WEB-INF\src\org\crazyit\app\action\RegistAction.java


  1. public class RegistAction extends ActionSupport  
  2. {  
  3.     private String name;  
  4.     private String pass;  
  5.     private int age;  
  6.     private Date birth;  
  7.     //省略了4个属性的setter和getter方法  
  8.     ...  
  9.     public void validate()  
  10.     {  
  11.         System.out.println("进入validate方法进行校验" 
  12.             + name);  
  13.         //要求用户名必须包含crazyit子串  
  14.         if(!name.contains("crazyit"))  
  15.         {  
  16.             addFieldError("user" ,   
  17.                 "您的用户名必须包含crazyit!");  
  18.         }  
  19.     }  
  20. }  

上面的粗体字代码重写了validate方法,在validate方法中,一旦发现校验失败,就把校验失败提示通过addFieldError方法添加进系统的FieldError中,这与类型转换失败后的处理是完全一样的。除此之外,程序无须做额外的处理,如果Struts 2发现系统的FieldError不为空,将会自动跳转到input逻辑视图,因此依然必须在struts.xml文件中为该Actioninput逻辑视图指定视图资源。

除此之外,为了在input视图对应的JSP页面中输出错误提示,应该在该页面中增加如下代码:


  1. <!-- 输出类型转换失败提示和校验失败提示 -->  
  2. <s:fielderror/>  

上面的<s:fielderror/>标签专门负责输出系统的FieldError信息,也就是输出系统的类型转换失败提示和输入校验的失败提示。

如果在输入页面输入的用户名不包含crazyit字符串,我们将会看到如图4.19所示的界面。

手动完成输入校验

4.19  重写validate方法完成输入校验

在上面的validate方法中,如果校验失败,我们直接添加了校验失败的提示信息,并没有考虑国际化的问题。但这并不是太大的问题,因为ActionSupport类里包含了一个getText方法,该方法可以取得国际化信息。

2.重写validateXxx()方法

前面已经介绍过了,Struts 2Action类里可以包含多个处理逻辑,不同的处理逻辑对应不同的方法。即Struts 2Action类里定义了几个类似于execute的方法,只是方法名不是execute

如果我们的输入校验只想校验某个处理逻辑,也就是仅校验某个处理方法,则重写validate方法显然不够,validate()方法无法准确知道需要校验哪个处理方法。实际上,如果我们重写了Actionvalidate方法,则该方法会校验所有的处理逻辑。

为了实现校验指定处理逻辑的功能,Struts 2Action允许提供一个validateXxx()方法,其中xxx即是Action对应的处理逻辑方法。

下面对上面的Action进行改写,为该Action增加regist,并增加validateRegist()方法。修改后的RegistAction类代码如下。

程序清单:codes\04\4.2\validateXxx\WEB-INF\src\org\crazyit\app\actionRegistAction.java

 


  1. public class RegistAction extends ActionSupport  
  2. {  
  3.     //该Action的4个属性  
  4.     private String name;  
  5.     private String pass;  
  6.     private int age;  
  7.     private Date birth;  
  8.     //此处省略4个属性的setter和getter方法  
  9.     ...  
  10.     public String regist()  
  11.     {  
  12.         return SUCCESS;  
  13.     }  
  14.     public void validate()  
  15.     {  
  16.         …  
  17.     }  
  18.     public void validateRegist()  
  19.     {  
  20.         System.out.println("进入validateRegist方法进行校验" 
  21.             + name);  
  22.         //要求用户名必须包含.org子串  
  23.         if(!name.contains(".org"))  
  24.         {  
  25.             addFieldError("user" ,   
  26.                 "您的用户名必须包含.org!");  
  27.         }  
  28.     }  
  29. }  

实际上,上面的validateRegist方法与前面的regist方法大致相同,此处仅仅是为了讲解如何通过提供validateXxx方法来实现只校验某个处理逻辑。

为了让该Actionregist方法来处理用户请求,必须在struts.xml文件中指定该方法。struts.xml文件的代码如下。

程序清单:codes\04\4.2\validateXxx\WEB-INF\src\struts.xml


  1. <?xml version="1.0" encoding="GBK"?>  
  2. <!-- 指定Struts 2配置文件的DTD信息 -->  
  3. <!DOCTYPE struts PUBLIC  
  4.     "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" 
  5.     "http://struts.apache.org/dtds/struts-2.1.7.dtd">  
  6. <struts>  
  7.     <!-- 指定Struts 2应用的国际化资源文件 -->  
  8.     <constant name="struts.custom.i18n.resources" value="mess"/>  
  9.     <!-- 指定Struts 2应用编码的字符集 -->  
  10.     <constant name="struts.i18n.encoding" value="GBK"/>  
  11.     <package name="lee" extends="struts-default">  
  12.         <!-- 定义处理用户请求的regist Action,使用.RegistAction的regist  
  13.             方法处理用户请求 -->  
  14.         <action name="registPro" class="org.crazyit.app.action.RegistAction" 
  15.             method="regist">  
  16.             <result name="input">/WEB-INF/content/regist.jsp</result>  
  17.             <result>/WEB-INF/content/show.jsp</result>  
  18.         </action>  
  19.         <action name="*">  
  20.             <result>/WEB-INF/content/{1}.jsp</result>  
  21.         </action>  
  22.     </package>  
  23. </struts>  

在上面名为registProAction中,指定使用RegistActionregist方法处理用户请求。如果浏览者再次向registPro提交请求,该请求将由RegistActionregist处理逻辑处理,那么不仅validate()方法会进行输入校验,validateRegist()方法也会执行输入校验。

如果我们在本应用的regist.jsp页面中输入不符合要求,将看到如图4.20所示的页面。

手动完成输入校验

 

从图4.20中可以看出,当用户向regist方法发送请求时,该Action内的validate方法和validateRegist方法都会起作用,而且validateRegist方法首先被调用。

前面已经介绍过了,不管用户向Action的哪个方法发送请求,Action内的validate方法都会被调用。如果该Action内还有该方法对应的validateXxx方法,则该方法会在validate方法之前被调用。

通过上面示例的介绍,我们不难发现Struts 2的输入校验需要经过如下几个步骤:

 类型转换器负责对字符串的请求参数执行类型转换,并将这些值设置成Action的属性值。

 在执行类型转换过程中可能出现异常,如果出现异常,将异常信息保存到ActionContext中,conversionError拦截器负责将其封装到FieldError里,然后执行第3步;如果转换过程没有异常信息,则直接进入第3步。

 使用Struts 2应用中所配置的校验器进行输入校验。

 通过反射调用validateXxx()方法,其中Xxx是即将处理用户请求的处理逻辑所对应的方法。

 调用Action类里的validate()方法。

 如果经过上面5步都没有出现FieldError,将调用Action里处理用户请求的处理方法;如果出现了FieldError,系统将转入input逻辑视图所指定的视图资源。图4.21显示了Struts 2表现层数据的整套处理流程。

 

手动完成输入校验



 

本文转自fkJava李刚 51CTO博客,原文链接http://blog.51cto.com/javaligang/887139: ,如需转载请自行联系原作者

上一篇:手把手教你写Linux I2C设备驱动


下一篇:我要和import说再见了!这个Python库能让我偷偷懒