Struts2提供了基于验证框架的输入校验,在这种校验方式下,所有的输入校验只需要通过指定的配置文件即可。Struts2中每个Action都有一个校验文件,其规则为:<Action名字>-validation.xml。如:

package com.struts.test.action;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class RegistAction extends ActionSupport {
    
private static final long serialVersionUID = -2113900523366315993L;
    
    
//该请求包含的4个请求参数
    private String name;
    
private String pass;
    
private int age;
    
private Date birth;
    
    
    
public String getName() {
        
return name;
    }

    
public void setName(String name) {
        
this.name = name;
    }

    
public String getPass() {
        
return pass;
    }

    
public void setPass(String pass) {
        
this.pass = pass;
    }

    
public int getAge() {
        
return age;
    }

    
public void setAge(int age) {
        
this.age = age;
    }

    
public Date getBirth() {
        
return birth;
    }

    
public void setBirth(Date birth) {
        
this.birth = birth;
    }

}

    在类RegistAction.class相同目录下有RegistAction-validation.xml文件:

<? xml version="1.0" encoding="GBK" ?>
<!-- 指定校验配置文件的DTD信息 -->
<! DOCTYPE validators PUBLIC 
    "-//OpenSymphone GROUP/ /XWork Validator 1.0.2/ /EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"
>
<!-- 校验文件的根元素 -->
< validators >
    
<!-- 校验Action的name属性 -->
    
< field  name ="name" >
        
<!-- 指定name属性必须满足必填规则 -->
        
< field-validator  type ="requiredstring" >
            
< param  name ="trim" > true </ param >
            
< message > 必须输入名字 </ message >
        
</ field-validator >
        
<!-- 指定name属性必须匹配正则表达式 -->
        
< field-validator  type ="regex" >
            
< param  name ="expression" > <![CDATA[ (\w{4,25}) ]]> </ param >
            
< message > 您输入的用户名只能是字母和数字,且长度必须在4到25之间 </ message >
        
</ field-validator >
    
</ field >
    
<!-- 校验Action的pass属性 -->
    
< field  name ="pass" >
        
<!-- 指定pass属性必须满足必填规则 -->
        
< field-validator  type ="requiredstring" >
            
< param  name ="trim" > true </ param >
            
< message > 必须输入密码 </ message >
        
</ field-validator >
        
<!-- 指定pass属性必须匹配正则表达式 -->
        
< field-validator  type ="regex" >
            
< param  name ="expression" > <![CDATA[ (\w{4,25}) ]]> </ param >
            
< message > 您输入的密码只能是字母和数字,且长度必须在4到25之间 </ message >
        
</ field-validator >
    
</ field >
    
<!-- 校验Action的age属性 -->
    
< field  name ="age" >
        
<!-- 指定age属性必须在指定范围内 -->
        
< field-validator  type ="int" >
            
< param  name ="min" > 1 </ param >
            
< param  name ="max" > 150 </ param >
            
< message > 年龄必须在1到150之间 </ message >
        
</ field-validator >
    
</ field >
    
<!-- 校验Action的birth属性 -->
    
< field  name ="birth" >
        
<!-- 指定birth属性必须在指定范围内 -->
        
< field-validator  type ="date" >
            
< param  name ="min" > 1900-01-01 </ param >
            
< param  name ="max" > 2050-02-21 </ param >
            
< message > 生日必须在${min}到${max}之间 </ message >
        
</ field-validator >
    
</ field >
</ validators >

    增加了这个校验文件后,系统会自动加载该文件,当用户提交请求的时候,Struts2的校验框架会根据该文件对用户的请求进行校验。当校验失败后,Struts2会自动返回名为input的逻辑视图。我们可以在视图中添加<s:fielderror/>来查看所返回的校验失败信息。

    上面的校验中,我们没有使用国际化,如需国际化,可将message配置成<message key="name.required">这样的形式。

    上述的校验是在服务器端进行的,如果需要在客户端进行校验,可以将jsp改成struts2的标签格式,如:

< html >
    
< head />
        
<!-- 可以导入一些CSS的样式 -->
    
< s:head />   
    
< body >
                
<!-- 添加validate='true'来进行校验 -->
        
< s:form  action ="regist.action"  validate ="true" >
            
< s:textfield  label ="用户名"  name ="name" />
            
< s:textfield  label ="密码"  name ="pass" />
            
< s:textfield  label ="年龄"  name ="age" />
            
< s:textfield  label ="生日"  name ="birth" />
            
< s:submit />
        
</ s:form >
    
</ body >
</ html >

    这里需要注意的是,国际化中需要使用<message>${getText("name.required")}</message>这样的形式。同时,客户端校验仅仅支持如下校验器:

  •     required validator(必填校验器)
  •     requiredstring validator(必填字符串校验器)
  •     string length validator(字符串长度校验器)
  •     regex validator(正则表达式校验器)
  •     email validator(邮件校验器)
  •     url validator(网址校验器)
  •     int validator(整数校验器)
  •     double validator(双精度数校验器)

    Struts2提供了两种方式来配置校验规则:字段校验器和非字段校验器风格。这两种风格其实并没有本质的不同,只是组织校验规则的方式不同:一种是字段优先,称为字段校验器风格;另外一种是校验器优先,称为非字段校验器风格。

    上面的例子RegistAction-validate.xml就是字段优先校验器风格。如果变成非字段校验器风格,则如下:

<? xml version="1.0" encoding="GBK" ?>
<!-- 指定校验配置文件的DTD信息 -->
<! DOCTYPE validators PUBLIC 
    "-//OpenSymphone GROUP/ /XWork Validator 1.0.2/ /EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"
>
<!-- 校验文件的根元素 -->
< validators >
    
< validator  type ="requiredstring" >
        
< param  name ="fieldName" > name </ param >
        
< param  name ="trim" > true </ param >
        
< message > ${getText("name.requried")} </ message >
    
</ validator >
    
< validator  type ="regex" >
        
< param  name ="fieldName" > name </ param >
        
< param  name ="trim" > true </ param >
        
< param  name ="expression" > <![CDATA[ (\w{4,25}) ]]> </ param >
        
< message > ${getText("name.requried")} </ message >
    
</ validator >
    
</ validators >

    上面的校验操作并没有使用短路操作,即当我们使用空字符串提交页面的时候,会发现error信息是:"您必须输入用户名! 您输入的用户名只能是字母和数字,且长度必须在4到25之间!"。为了达到短路效果,我们可以在<validator.../>元素或<field-validator.../>元素中增加short-curcuit="true"即可。我们在例子中将name和pass的必填校验器配置成校验器,那么当必填校验器失败后,同一字段的其他校验器就不会继续校验了。

    我们总结一下校验顺序和短路:

    校验器的执行顺序有如下原则:

          所有非字段风格的校验器优先于字段风格的校验器

          所有非字段风格的校验器中,排在前面的会先执行。

          所有字段风格的校验器中,排在前面的会先执行。

    校验器短路的原则是:

        所有非字段校验器是最优先执行,如果某个非字段校验器校验失败了,则该字段上所有字段校验器都不会获得校验的机会。

        非字段校验器的校验失败,不会阻止其他非字段校验的执行。

        如果一个字段校验器校验失败后,则该字段下的且排在该校验失败的校验器之后的其他字段校验器不会获得校验的机会。

        字段校验器永远不会阻止非字段校验器的执行。

    Strut2的一个Action中可能包含多个处理逻辑,当一个Action类包含多个类似于execute的方法时,每个方法都是一个处理逻辑。不同的处理逻辑需要不同的校验规则,Struts2也提供了对不同Action指定不同校验规则的的支持。

    当需要让一个Action可以处理多个请求时,需要配置多个逻辑的Action,如:


 

         < action  name ="regist"  class ="com.struts.test.action.RegistAction" >
            
< result  name ="input" > /regist.jsp </ result >
            
< result  name ="error" > /error.jsp </ result >
            
< result > /show.jsp </ result >
        
</ action >

        
< action  name ="login"  class ="com.struts.test.action.RegistAction"  method ="login" >
            
< result  name ="input" > /login.jsp </ result >
            
< result  name ="error" > /error.jsp </ result >
            
< result > /show.jsp </ result >
        
</ action >