| 
 | 
 
| 
 
 在Struts2应用中提供验证的方式有两种——编程式和声明式。 
 
编程式验证 
 
要提供编程式验证的话,action就要实现Validateable接口。该接口只有一个方法,在方法中需要执行验证操作:void validate(); 
 
为了将验证中出现的问题反馈给用户,action还需要实现ValidationAware接口。这个接口更为复杂一些,它里面的方法可以用来添加验证错误,判断当前是否有验证错误,等等。 
 
如果可能的话,你的action可以继承ActionSupport类,在该类中提供了以上这些接口的缺省实现。只有当验证操作极其复杂的时候,我们才该使用编程式验证。更好的解决方案是采用声明式验证。下面是一个编程式验证的小例子: 
 
public class UserAction extends ActionSupport{     
    
       private String userName;     
    
       private String password     
    
       public void validate() {     
    
              if(userName ==null || userName.trim().equals("")){     
    
                     this.addFieldError("userName", "用户名不能为空");     
    
                     // this.addFieldError("userName", this.getText("error.login.username.null"));       
    
//从配置文件得到数据     
    
              }else if(!Pattern.matches( "^[a-zA-Z][a-zA-Z0-9_]{3,14}$" , userName)){     
    
                     this.addFieldError("userName", "用户名必须以字母开始,字母、数字或_, ");     
    
                     // this.addFieldError("userName", this.getText("error.login.username.match"));     
    
              }     
    
                   
    
              if(password == null || password.equals("")){     
    
                     this.addFieldError("password", "密码不能为空");     
    
                     // this.addFieldError("password", this.getText("error.login.password.null"));     
    
              }else if(!Pattern.matches("^[a-zA-Z0-9!@#]{4,15}$", password)){     
    
                     this.addFieldError("password", "密码可以由字母、数字和! @ # 组成 ");     
    
                     // this.addFieldError("password", this.getText("error.login.password.match"));     
    
              }     
    
       }     
    
       public String login() throws Exception {           
    
              if(this.hasFieldErrors()){  //判断是否有错误信息     
    
                     return INPUT;     
    
              }     
    
              return SUCCESS;     
    
       }     
    
}     
    
 验证会与执法方法配置:比如:login 
 
它的执行顺序为:validate()  à  validateLogin() 
 
 
声明式验证 
 
 
每一个需要声明式验证的action都需要在类中进行注解或者要有一个相应的XML文件。对于MyAction这个类,其XML文件就是“MyAction-validation.xml”,并会和它放在同一个包(package)下面。处理这个action的拦截器栈需要包含有“validation”(用来进行验证)和“workflow”(当验证失败时用来进行重定向,以返回到“input”结果)拦截器。这样的拦截器栈有以下几个:“validationWorkflowStack”,“paramsPrepareParamsStack”,“defaultStack”和“completeStack”。 
 
下面是验证文件的一个例子: 
 
<!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="count">    
    
              <field-validator type="int" short-circuit="true">    
    
                     <param name="min">1</param>    
    
                     <param name="max">100</param>    
    
                     <message key="invalid.count">    
    
                     Value must be between ${min} and ${max}     
    
                     </message>    
    
              </field-validator>    
    
       </field>    
    
       <field name="name">    
    
              <field-validator type="requiredstring">    
    
                     <message>You must enter a name.</message>    
    
              </field-validator>    
    
       </field>    
    
       <validator type="expression" short-circuit="true">    
    
              <param name="expression">email.equals(email2)</param>    
    
              <message>Email not the same as email2</message>    
    
       </validator>    
    
</validators>    
    
 
1、  每一个字段都可以含有一个或多个“field-validator”节点 
 
2、  每一个字段的validator是按照定义顺序执行的 
 
3、  每一个字段的validator都有一个“short-circuit”属性;如果其值为true而验证失败,那么剩下的所有验证都会被跳过,该字段就会直接返回一个失败的结果 
 
4、  Message节点可以包含一个“key”属性,用来从message bundle中查找需要显示给用户的消息;如果找不到对应的message bundle key的话,那么就返回节点的value属性的值 
 
5、  Validator的配置信息(例如min和max)和值栈中的值一样,都可以通过把值放在“${”和“}”之间,来显示到验证消息中。 
 
6、  Validators 的作用域可以是“field”或者“expression”;具有“expression”作用域的validator可以同时作用于多个字段 
 
下面是关于validator类型和相应描述的一个完整列表。在http://struts.apache.org/2.x/docs/validation.html可以得到包括配置相关的更多信息。 
 
名称 
 描述 
  
required 
 确保该属性不是null 
  
requiredstring 
 确保一个String类型的属性不是null,并且非空 
  
stringlength 
 检查String的长度范围是否与所期望的一致 
  
int 
 检查int类型的数字是否超出所期望的大小范围 
  
double 
 检查double类型的数字是否超出所期望的大小范围 
  
date 
 检查date类型的属性是否超出所期望的范围 
  
expression 
 使用值栈来估算一个ONGL表达式(必须要返回boolean值) 
  
fieldexpression 
 使用OGNL表达式来验证字段 
  
email 
 保证该属性是一个有效的email地址 
  
url 
 保证该属性是一个有效的URL 
  
conversion 
 检查该属性是否有转换错误 
  
regex 
 检查该属性的值是否与某个正则表达式相匹配。 
  
visitor 
 Visitor validator可以把对字段的验证动作推迟到这个字段所属的类的特有的另一个验证文件中执行。 
 
比如说,你在使用模型驱动的action,在模型中有一个对应于Person类的“person”属性。如果该模型正在被多个Action使用,那么你大概就会想要把验证信息抽取出来进行重用。Visitor 验证提供了这样的功能 
  
 
 
另外,你还可以创建自己的validator。你自定义的validator需要实现Validator接口(用于表达式验证)或FieldValidator接口(用于字段验证)。 
 
新的validator需要在“validators.xml”中注册,该文件存在于classpath的根目录下。通常这个文件可以从发行的JAR包中访问到,但是如果人为提供了这个文件的话,那么发行包中的文件就会被忽略。所以在添加新的validator之前,你需要从Struts2 JAR包中把“validators.xml”这个文件拷贝出来,放到项目classpath的根目录下,然后再把新的validator添加进去。这样当前已有的validator才会被包含到应用中来。和其他配置一样,validator的配置信息也很简单,只需要一个统一标识符和validator的类名。 
 
<validators>    
    
<validator name="postcode"  class="com.validators.PostCodeValidator"/>    
    
…     
    
</validators>    
     |   
 
 
 
 |