Struts 2.x权威指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

5.5.10 Visitor校验器

Visitor校验器主要用于校验Action里的复合属性,例如一个Action里包含了User类型的属性。假设有下面的Action类。

程序清单:codes\05\5.5\Visitor\WEB-INF\src\org\crazyit\struts2\action\RegistAction.java

public class RegistAction extends ActionSupport
{
    // Action里包含了一个User类型的属性
    private User user;
    // user属性的setter和getter方法
    public void setUser(User user)
    {
          this.user = user;
    }
    public User getUser()
    {
          return (this.user);
    }
}

这种方式非常类似于前面介绍的模型驱动,即User类是一个最普通的Java类,仅仅提供了4个属性,以及每个属性的setter和getter方法。该User类的代码片段如下。

程序清单:codes\05\5.5\Visitor\WEB-INF\src\org\crazyit\struts2\domain\User.java

public class User
{
    // User类里包含的4个基本数据类型的属性
    private String name;
    private String pass;
    private int age;
    private Date birth;
    // 此处省略了4个属性的setter和getter方法
    ...
}

为了校验上面RegistAction里的User属性,显然不能通过其他校验器完成,因为那些普通的校验器都只能校验基本数据类型和字符串类型。此时,为了校验该User类型属性里的其他属性,则应该使用Visitor校验器。

下面给出校验RegistAction的校验规则文件。

程序清单:codes\05\5.5\Visitor\WEB-INF\src\org\crazyit\struts2\action\RegistAction-validation.xml

<?xml version="1.0" encoding="GBK"?>
<!-- 指定校验规则文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
    "-//OpenSymphony Group//XWork Validator 1.0.3//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- 校验规则文件的根元素 -->
<validators>
    <!-- 指定校验user字段 -->
    <field name="user">
          <!-- 使用Visitor校验器 -->
          <field-validator type="visitor">
                <!-- 指定校验规则文件的context -->
                <param name="context">userContext</param>
                <!-- 指定校验失败后提示信息是否添加下面前缀 -->
                <param name="appendPrefix">true</param>
                <!-- 指定校验失败的提示信息前缀 -->
                <message>用户的:</message>
          </field-validator>
    </field>
</validators>

上面的校验规则并未指定User类里各字段应该遵守怎样的校验规则,因此还需要为User类指定对应的校验规则文件。在默认情况下,该校验规则文件的文件名为User-validation.xml,因为配置 Visitor 校验器时指定了 context 为 userContext,则该校验规则文件的文件名为User-userContext-validation.xml。该文件的代码如下。

程序清单:codes\06\6.5\Visitor\WEB-INF\src\org\crazyit\struts2\domain\User-userContext-validation.xml

<?xml version="1.0" encoding="GBK"?>
<!-- 指定校验规则文件的DTD信息 -->
<!DOCTYPE validators PUBLIC
    "-//OpenSymphony Group//XWork Validator 1.0.3//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
<!-- 校验文件的根元素 -->
<validators>
    <!-- 校验User属性的name属性 -->
    <field name="name">
          <!-- 指定name属性必须满足必填规则 -->
          <field-validator type="requiredstring">
                <param name="trim">true</param>
                <!-- 如果校验失败,输出name.requried对应的国际化信息 -->
                <message>${getText('name.requried')}</message>
          </field-validator>
          <!-- 指定name属性必须匹配正则表达式 -->
          <field-validator type="regex">
                <param name="expression"><![CDATA[(\w{4,25})]]></param>
                <!-- 如果校验失败,输出name.regex对应的国际化信息 -->
                <message>${getText('name.regex')}</message>
          </field-validator>
    </field>
    <!-- 校验User属性的pass属性 -->
    <field name="pass">
          <!-- 指定pass属性必须满足必填规则 -->
          <field-validator type="requiredstring">
                <param name="trim">true</param>
                <!-- 如果校验失败,输出pass.requried对应的国际化信息 -->
                <message>${getText('pass.requried')}</message>
          </field-validator>
          <!-- 指定pass属性必须满足匹配指定的正则表达式 -->
          <field-validator type="regex">
                <param name="expression"><![CDATA[(\w{4,25})]]></param>
                <!-- 如果校验失败,输出pass.regex对应的国际化信息 -->
                <message>${getText('pass.regex')}</message>
          </field-validator>
    </field>
    <!-- 指定User属性的age属性必须在指定范围内-->
    <field name="age">
          <field-validator type="int">
                <param name="min">1</param>
                <param name="max">150</param>
                <!-- 如果校验失败,输出age.range对应的国际化信息 -->
                <message>${getText('age.range')}</message>
          </field-validator>
    </field>
    <!-- 指定User属性的birth属性必须在指定范围内-->
    <field name="birth">
          <field-validator type="date">
                <!-- 下面指定日期字符串时,必须使用本Locale的日期格式 -->
                <param name="min">1900-01-01</param>
                <param name="max">2050-02-21</param>
                <!-- 如果校验失败,输出birth.range对应的国际化信息 -->
                <message>${getText('birth.range')}</message>
          </field-validator>
    </field>
</validators>

从上面的配置文件中可以看出,这个User-userContext-validation.xml文件的内容与之前校验Action的校验文件完全相同,通过这种方式就可以对Action里复合类型的属性进行校验了。

注意

这个对模型类(User类)进行校验的校验规则文件必须与模型类(User类)放在同一个目录下。

因为Action里的属性不再是基本数据类型,而是User类型的属性,则对JSP页面进行简单的修改:将表单域直接绑定到user属性的属性。修改后JSP页面的表单部分代码如下。

程序清单:codes\05\5.5\Visitor\WEB-INF\content\registForm.jsp

<!-- 使用Struts 2标签库生成表单 -->
<s:form action="regist">
    <!-- 使用s:textfield标签生成文本输入框 -->
    <s:textfield label="用户名" name="user.name"/>
    <s:password label="密码" name="user.pass"/>
    <s:textfield label="年龄" name="user.age"/>
    <s:textfield label="生日" name="user.birth"/>
    <s:submit/>
</s:form>

在上面表单域的name属性中,指定了这些表单域的名字为user.pass、user.age等,这就意味着将这些属性直接绑定到Action实例的user属性的pass、age属性。

如果浏览者的输入不能通过输入校验,将看到如图5.10所示的页面。

图5.10 Visitor校验器的校验效果

在图5.10 中看到校验提示信息是:“用户的:必须输入用户名”等。其中“用户的:”字符串是在配置Visitor校验器时指定的<message .../>元素的内容,如果我们指定appendPrefix属性值为true,则会在提示信息中增加该前缀,否则不会添加该前缀。