一. 基于验证框架的输入校验 (服务器端验证)
1. 编写校验配置文件:命名规则:action类名-validatin.xml.
2. 一个action对应多个逻辑处理方法:指定校验摸个特定方法的方式:
action类名-name属性名-validatin.xml.(name属性名:在strtus配置文件中的)
3. 配置文件存放位置:放在与Action相同的文件夹内。
4. 验证规则:先加载action类名-validatin.xml,然后加载action类名-name属性名-validatin.xml文件。
5. 校验器的配置风格:两种:字段校验器,非字段校验器。
字段校验器配置格式:
<field name="被校验的字段">
<field-validator type="校验器名">
<!--此处需要为不同校验器指定数量不等的校验规则-->
<param name="参数名">参数值</param>
....................
<!--校验失败后的提示信息,其中key指定国际化信息的key-->
<message key="I18Nkey">校验失败后的提示信息</message>
<!--校验失败后的提示信息:建议用getText("I18Nkey"),否则可能出现Freemarker template Error-->
</field-vallidator>
<!-- 如果校验字段满足多个规则,下面可以配置多个校验器-->
</field>
非字段校验器配置格式:
<validator type="校验器名">
<param name="fieldName">需要被校验的字段</param>
<!--此处需要为不同校验器指定数量不等的校验规则-->
<param name="参数名">参数值</param>
<!--校验失败后的提示信息,其中key指定国际化信息的key-->
<message key="I18Nkey">校验失败后的提示信息</message>
<!--校验失败后的提示信息:建议用getText("I18Nkey"),否则可能出现Freemarker template Error-->
</validator>
非字段校验:先指定校验器:由谁来校验,来校验谁!
字段校验器:先指定校验的属性:我来校验谁,由谁来校验!
二. 客户端验证
增加客户端校验非常简单,将输入页面的表单元素改为使用struts2标签来生成表单,并且为该表单增加validate="true"属性即可,即将编写好的服务器端校验(少部分不能)转换为客户端验证,省去手动添加js校验的麻烦(相当于你照着步骤一写好了服务器端的验证,加上validate="true",那么你的客户端验证也写好了)
三.短路校验器
短路校验器:只需在<validator>或<filed-validator>元素中添加short-circuit=”true”属性。(如果校验失败则之后的将不会执行校验),防止出现用户输入为空时出现多条提示信息(如:1请不能为空,2长度必须大于10)
注意:校验器的短路原则
1. 所有非字段检验器时最优先执行的,如果某个非字段校验器校验失败了,则该字段上的所有字段校验器都不会获得校验机会;
2. 非字段校验校验失败,不会阻止其他非字段校验执行;
3. 如果一个字段校验器校验失败后,则该字段下且排在该校验失败后的检验器之后的其他字段校验器不会获得校验机会; (服务器转换成客户端校验时,如果字段校验失败,那么之后所有字段都失效,仅限于客户端,服务器端不变)
4. 字段校验器永远不会阻止非字段校验器的执行!
四. 校验文件的搜索规则
Struts 2的一个Action中可能包含了多个处理逻辑,当一个Action类中包含多个类似于execute的方法时,每个方法都是一个处理逻辑。不同的处理逻辑可能需要不同的校验规则,Struts 2允许为不同控制逻辑指定不同校验规则的支持。
当需要让一个Action可以处理多个请求时,应该在配置该Action时指定method属性。通过这种方式,就可以将一个Action处理类配置成多个逻辑Action。
如果系统中包含了两个Action:BaseAction和RegistAction,其中RegistAction继承了BaseAction,且两个Action都指定了对应的配置文件,则RegistAction对应Action的校验规则实际上是RegistAction-validation.xml和BaseAction-validation.xml两个文件中规则的总和。
假设系统有两个Action:BaseAction和RegistAction,则系统搜索规则文件顺序如下:
(1)BaseAction-validation.xml
(2)BaseAction-方法名-validation.xml
(3)RegistAction-validation.xml
(4)RegistAction-方法名-validation.xml
这种搜索与其他搜索不同的是,即使找到第一个校验规则,系统还会继续搜索,不管有没有这 4 份文件,也不管是否找到配置文件,系统总是按固定顺序搜索(即RegistAction含4个校验规则文件)
Struts 2搜索规则文件是从上而下的,实际用的校验规则是所有校验规则的总和。如果两个校验文件中指定的校验规则冲突,则后面文件中的校验规则取胜。
五.内置校验器
struts2提供了大量的内置校验器:你可以在xwork-core-2.1.6.jar的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"/>(重点:visitor实现了复合属性的校验,看到此处,google一下,能了解的更透测)
<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>
六. 手动输入校验
在Action类里重写父类的validate()方法即可。
在上面的validate方法中,一旦发现校验失败,就把失败提示通过addFieldError方法添加到系统的fieldError中。校验完毕后,若系统的fieldError不为空,则自动转到input视图对应的JSP页面中输出错误提示,这与类型转换失败后的处理是完全一样的。
这里不能忽略另外种情况:
Struts2的Action类里可以包含多个处理逻辑,不同的处理逻辑对应不同的方法。即Struts2的Action类里定义了几个类似于execute的方法,只是方法名不同。而重写validate方法无法知道需要校验的是哪个处理逻辑。实际上重写validate方法会校验所有的处理逻辑。
为了校验指定处理逻辑,需提供一个validateXxx()方法,其中xxx为Action对应的处理逻辑方法。
例如Action类里有个login()逻辑方法,那么对应的校验方法validateLogin()方法。
但之后还是会调用validate()进行校验,因此此时validate()没必要写了,或者让validate()进行公共字段的校验。
七. 基于annotation的输入校验
此处类似于servlet的annotation配置,属于struts2的“零配置”的特性,下面给出一份例子,一目了然
package org.crazyit.app.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.validator.annotations.*; import java.util.Date; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee [email protected] * @version 1.0 */ public class RegistAction extends ActionSupport { private String name; private String pass; private int age; private Date birth; //name属性的setter和getter方法 //使用Annotation指定必填、正则表达式两个校验规则 @RequiredStringValidator(key = "name.requried" , message = "") @RegexFieldValidator(expression = "\\w{4,25}" ,key = "name.regex" , message = "") public void setName(String name) { this.name = name; } public String getName() { return this.name; } //pass属性的setter和getter方法 @RequiredStringValidator(key = "pass.requried" ,message = "") @RegexFieldValidator(expression = "\\w{4,25}" ,key = "pass.regex" ,message = "") public void setPass(String pass) { this.pass = pass; } public String getPass() { return this.pass; } //age属性的setter和getter方法 @IntRangeFieldValidator(message = "" , key = "age.range", min = "1" , max = "150") public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } //birth属性的setter和getter方法 //使用Annotation指定日期范围校验规则 @DateRangeFieldValidator(message = "" , key = "birth.range", min = "1900/01/01" , max = "2050/01/21") public void setBirth(Date birth) { this.birth = birth; } public Date getBirth() { return this.birth; } }
之前的校验规则文件都可以删除缺点:维护困难
优点:简化应用开发,无需编写XML文件