Struts2声明式验证包含两部分:
(1)字段验证:针对某个字段的输入验证,如是否为空等
(2)非字段验证:针对多个字段输入的逻辑关系,如两次输入的密码是否相等

一、字段验证
(1)确定要验证的字段
(2)编写验证程序的配置文件
  ①若当前Action类的多个请求使用同一验证规则,则在当前Action的包下新建一个文件,文件名:Action类的类名-validation.xml
  <validators>
    <field name="count">
    <!-- count是待验证的字段 -->
      <field-validator type="int">
      <!-- type的取值是struts2内建的验证规则的名称 -->
        <param name="min">1</param>
        <param name="max">10</param>
        <message>count必须在1到10之间</message>
      </field-validator>
    </field>
  </validators>
  ②若当前Action类的多个请求使用不同的验证规则,则在当前Action的包下为每一个action请求新建一个配置文件,文件名:Action类的类名-action请求的名字-validation.xml
  (配置的内容一样)
(3)确定验证失败时的响应页面
  当前<action>必须配置一个<result name="input">……</result>
(4)验证提示消息的显示
  <s:form>的主题不是simple时,自动显示。
  simple主题:<s:fielderror name="count"/>(推荐)或${fieldErrors.count[0] }或${errors.count[0] }

二、非字段验证
(1)确定要验证的字段
(2)编写验证程序的配置文件
  <validators>
    <validator type="expression">
      <param name="expression"><![CDATA[password==password1]]></param>
      <message>两次输入的密码必须一致</message>
    </validator>
  </validators>
(3)确定验证失败时的响应页面
  当前<action>必须配置一个<result name="input">……</result>
(4)验证提示消息的显示
  非字段验证并不是某个字段的错误,所以:<s:actionError />

三、如何进行验证
  validation拦截器(默认拦截器栈的一员)负责加载和执行验证程序
  struts2的每一个验证规则与一个具体的验证器类想关联,在验证过程中,由validation拦截器调用验证器类进行验证。

四、验证提示消息的国际化
  在国际化资源文件中,键入message.count=……
  在验证程序的配置文件中,修改<message>节点为:
  <message key="message.count"></message>
  或
  <message key="%{getText('message.count')}"></message>

五、验证提示消息的重用
  如果多个字段使用了相同的验证规则,如下:
  <field name="count">
  <!-- count是待验证的字段 -->
    <field-validator type="int">
      <param name="min">1</param>
      <param name="max">10</param>
      <message key="message.int"></message>
    </field-validator>
  </field>
  <field name="age">
    <field-validator type="int">
      <param name="min">20</param>
      <param name="max">50</param>
    <message key="%{getText('message.int')}"></message>
    </field-validator>
  </field>
  例如,count和age字段都使用了int验证规则,且验证提示消息都是“……的值必须在……和……之间”,可以考虑验证提示消息的重用:它们的提示消息都是从国际化资源文件中获取键为message.int的值
  在国际化资源文件中,message.int=${getText(fieldName) }的值必须在${min }和${max }之间。
  注:fieldName、min、max三个属性都存在于值栈中
  (在国际化资源文件中如何获取值栈中的属性值,如何访问国际化资源文件,参看:http://www.cnblogs.com/duanjiapingjy/p/7747539.html)

六、自定义验证器
  1.自定义一个类
    如果自定义验证器是为了实现普通的验证程序,建议extends ValidatorSupport
    如果自定义验证器是为了实现字段的验证程序,建议extends FieldValidatorSupport
    编写重写的方法validate(可以参看struts2内建的验证规则对应的验证器)
    public class XXXValidator extends FieldValidatorSupport {
      @Override
      public void validate(Object object) throws ValidationException {
        //获取相应的字段名和字段值
        String fieldName = getFieldName();
        Object fieldValue = getFieldValue(fieldName, object);
        //进行验证
        boolean result = ...;
        //如果验证失败,添加错误消息
        if(!result){
          addFieldError(fieldName, object);
        }
      }
    }
  2.注册自定义的验证程序
    在类路径下新建一个文件,文件名:validators.xml
    <validators>
      <validator name="自定义验证规则的名称" class="自定义验证器的全类名"/>
    </validators>
  3.使用自定义验证器(同字段验证的过程)
  (1)确定要验证的字段
  (2)在字段所在类的包下新建一个文件,文件名:Action类的类名-validation.xml
    <validators>
      <field name="待验证字段的名字">
        <field-validator type="自定义验证规则的名称">
          <message>……</message>
        </field-validator>
      </field>
    </validators>
  注:如果想要在验证程序中接受一个参数(<field-validator>节点下的<param>子节点),则需要在自定义的验证器类中增加相应的属性
  (3)确定验证失败时的响应页面
    当前<action>必须配置一个<result name="input">……</result>
  (4)验证提示消息的显示