我的Blog我做主^_^

走向一条通往JAVA的不归路...

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  64 随笔 :: 68 文章 :: 77 评论 :: 0 Trackbacks

Validator 检查你的表单

作者: James Holmes

Validator (验证器)提供的丰富的内置验证方法简化 Struts 的开发过程。

      Struts 框架的一个主要好处是它提供了对接收到的表单数据进行验证的内置界面。如果有任何验证失败,则应用程序都会重新显示 HTML 表单,这样就可以改正无效的数据了。如果验证成功,则处理过程会继续进行。 Struts 框架的简单验证界面会减少与处理数据验证有关的令人头疼的事情,这样你就可以把精力集中到验证代码上,而不是放到捕获数据、重新显示不完整或无效数据的技巧上。

但是, Struts 内置的验证界面也有缺点。例如,在整个应用程序中验证代码常常会大量重复,因为许多域需要相同的验证逻辑。对一些相似字段的验证逻辑进行任何修改都要求在几个地方修改代码,还要重新编译受影响的代码。为了解决这个问题并增强 Struts 验证界面的功能,作为 Struts 的第三方附加件创建了 Validator 框架。后来, Validator 被集成到核心 Struts 代码库中,并从 Struts 中分离出来,现在它是一个独立的 Jakarta Commons 项目。虽然 Validator 是一个独立的框架,但它仍能与其他程序封装在一起后提供,并与 Struts 无缝集成。


Validator
概述

      没有 Validator ,你就不得不编写验证表单数据所需的全部代码,并把它放入 Form Bean 对象的 validate( ) 方法中。对于想在其上进行数据验证的每个 Form Bean 域来说,都需要编写逻辑代码来实现验证。此外,你还必须编写代码来存储验证失败时的出错消息。

有了 Validator ,你就不必在 Form Bean 中编写用于验证或存储错误消息的任何代码。相反, Form Bean 提供了 Validator 的一个 ActionForm 子类,它提供验证或存储错误消息的功能。

可把 Validator 框架作为一个可用于 Form Bean 验证的可插入的验证例行程序系统来进行安装。每个验证例行程序都只是一个 Java 方法,负责执行特定类型的验证任务,验证可能通过,也可能失败。 默认情况下, Validator 与几个有用的验证例行程序封装在一起来提供,这些例行程序能满足大多数情况下的验证要求。但是,如果 Validator 框架没有提供你需要的验证例行程序,那么你可以自己创建定制的验证例行程序,并将它插入到该框架中。此外, Validator 还支持服务器端和客户端( JavaScript )的验证,而 Form Bean 只提供服务器端验证界面。

Validator 使用两个 XML 配置文件来分别确定安装哪个验证例行程序和如何将它们应用于给定的应用程序。第一个配置文件 validator-rules.xml 说明应该被插入到框架中的验证例行程序,并提供每个验证的逻辑的名称。 validator-rules.xml 文件还定义了每个验证例行程序的客户端 JavaScript 代码。可以配置 Validator 让它把这个 JavaScript 代码发送到浏览器上,这样验证就可以在客户端和服务器端进行了。

第二个配置文件 validation.xml 确定哪个验证例行程序应用到哪个 Form Bean 。文件中的定义使用 struts-config.xml 文件给出的 Form Bean 的逻辑名称以及 validator-rules.xml 文件给出的验证例行程序的逻辑名称,以便把二者关联起来。

使用 Validator 框架包括启用 Validator 插件、配置 Validator 的两个配置文件,以及创建提供 Validator ActionForm 子类的 Form Beans 。下面详细解释如何配置和使用 Validator


启用
Validator 插件

      虽然 Validator 框架是与 Struts 封装在一起提供的,但在默认状况下 Validator 并不被启用。为了启用 Validator ,要向你的应用程序的 struts-config.xml 文件中添加下面的插件定义。

<!-- Validator Configuration -->

<plug-in className="org.apache.struts

.validator.ValidatorPlugIn">

  <set-property property="pathnames"

               value="/WEB-INF/

  validator-rules.xml, /WEB-INF/

 

  validation.xml"/>

</plug-in>

该定义告诉 Struts 为你的应用程序加载并初始化 Validator 插件。在初始化时,该插件装入由路径名属性指定的、用逗号分隔的 Validator 配置文件清单。每个配置文件的路径应该用与 Web 应用程序的相关的路径来指定,如前面的例子所示。

请注意,你的应用程序的 struts-config.xml 文件必须与 Struts Configuration Document Type Definition Struts 配置文档类型定义, DTD )一致,后者规定文件中元素出现的顺序。所以,你必须把 Validator 插件定义放到该文件的适当位置。确保文件中元素适当排列的最简便方法就是使用诸如 Struts Console 的工具,它自动格式化你的配置文件,以便与 DTD 保持一致。


配置
validator-rules.xml

      Validator 框架可以设置为可插入系统,其验证例行程序仅仅是插入到该系统中执行具体验证的 Java 方法。 validator-rules.xml 文件说明性地插入 Validator 用于执行验证的验证例行程序中。 Struts 示例应用程序带有这个文件的预配置拷贝。在大多数情况下,你不必修改这个预配置拷贝,除非你要向该框架中添加自己定制的验证。

清单 1 是一个示例 validator-rules.xml 文件,说明如何将验证例行程序插入到 Validator 中。 validator-rules.xml 文件中的每个验证例行程序都有自己的定义,它用 validator 标记声明,利用 name 属性为该验证例行程序指定逻辑名,并指定该例行程序的类和方法。该例行程序的逻辑名称供该文件中的其他例行程序以及 validation.xml 文件中的验证定义用于引用该例行程序。

请注意, validator 标记放在 javascript 的标记中, javascript 标记用于定义客户端 JavaScript 代码,以便在客户端执行与服务器端相同的验证。


提供的验证程序

     默认情况下, Validator 中包括几个基本验证例行程序,你可以用它们来处理大多数验证问题。这些例行程序具有逻辑名称,如 required (用于输入要求的值)、 CreditCard (用于输入信用卡号码值)、 email (用于输入电子邮件地址值),等等。


创建
Form Bean

     为了使用 Validator ,你的应用程序的 Form Bean 必须归到 Validator ActionForm 的某一子类,而不是 ActionForm 本身。 Validator ActionForm 子类提供了 ActionForm validate( ) 方法(它嵌入到 Validator 框架中)的实施过程。你不必从头编写验证代码并把它投入 validate( ) 方法中,相反,可以完全忽略该方法,因为 Validator 为你提供了验证代码。

Struts 提供的核心功能相类似, Validator 提供给你两种可供选择的方法来创建 Form Bean 你可以选择的第一种方法就是像下面这样创建一个特定的 Form Bean 对象:

package com.jamesholmes.minihr;

 

import org.apache.struts.validator

.ValidatorForm;

 

 

public class LogonForm extends ValidatorForm {

  private String username;

  private String password;

 

  public String getUsername() {

    return username;

  }

 

  public void setUsername(String

username) {

    this.username = username;

  }

 

 

  public String getPassword() {

    return password;

  }

public void setPassword(String

password) {

    this.password = password;

  }

}

这个类与你不是用 Validator 所创建的类相似,但它提供 ValidatorForm 而不是 ActionForm 。这个类也不提供 ActionForm 的空 reset( ) validate( ) 方法的实施过程,因为 ValidatorForm 提供了相应过程。

struts-config.xml 文件中配置这个特定 Form Bean 的方法与配置正则 Form Bean 的方法相同:

<form-beans>

  <form-bean name="logonForm"

            type="com.jamesholmes

  .minihr.LogonForm"/>

</form-beans>

用表单标记的 name 属性给特定 Form Bean 指定的逻辑名是在定义 validation.xml 文件中的验证时所使用的名称,如下所示:

<!DOCTYPE form-validation

PUBLIC "-//Apache Software Foundation//

       DTD Commons Validator Rules

       Configuration 1.0//EN"

       "http://jakarta.apache.org/

      commons/dtds/validator_1_0.dtd">

 

 

<form-validation>

  <formset>

    <form name="logonForm">

      <field property="username"

            depends="required">

        <arg0 key="prompt.username"/>

      </field>

    </form>

  </formset>

</form-validation>

Validator 使用该表单标记的 name 属性的值将验证定义与要应用这些定义的 Form Bean 的名称相匹配。

创建 Form Bean 时可以选择的第二种方法是在 struts-config.xml 文件中定义一个动态 Form Bean ,如下所示:

<form-beans>

  <form-bean name="logonForm"

            type="org.apache

.struts.validator.DynaValidatorForm">

    <form-property name="username"

            type="java.lang.String"/>

    <form-property name="password"

            type="java.lang.String"/>

  </form-bean>

</form-beans>

动态 Form Bean 不要求创建特定的 Form Bean 对象;相反,要定义 Form Bean 应该具有的属性和类型,而 Struts 为你动态创建 Form Bean Validator 允许你使用这个概念,就像在核心 Struts 中使用这个概念一样。与使用 Validator 的惟一区别就是要指定 Form Bean org.apache.struts.validator.DynaValidatorForm 类型,而不是 org.apache.struts.action.DynaActionForm 类型。

分配给动态 Form Bean 的逻辑名是在定义 validation.xml 文件中的验证时使用的名称。 Validator 使用与之相匹配的名称将这些验证与 Form Bean 联系在一起。

除了创建 Form Bean 的这两种标准方法之外, Validator 还提供了一个高级特性,用于将多个验证定义与一个 Form Bean 定义联系起来。当你使用基于 validatorForm 或基于 DynaValidatorForm Form Bean 时, Validator 使用 struts-config.xml 文件中的 Form Bean 的逻辑名称,将 Form Bean 映射到 validation.xml 文件中的验证定义。这种机制在大多数情况下非常有用,但在某些时候, Form Bean 要在多个操作中共享。 一个操作可能使用 Form Bean 的所有域( fields ),而另一个操作可能只使用这些域的一个子集。因为验证定义被连接到 Form Bean ,所以只使用域的一个子集的操作就无法绕过对未使用域的验证。当验证 Form Bean 时,就会对未使用的域生成错误消息,因为 Validator 无从知道不去验证未使用的域,它只是简单地把它们看作缺失或无效。

为了解决这个问题, Validator 提供了两个附加的 ActionForm 子类,它使你能够将验证与操作相关联,而不是与 Form Bean 相关联。这样你就可以根据哪个操作正在使用 Form Bean 来指定把哪些验证用于该 Form Bean 了。对于特定的 Form Bean ,你要像下面这样声明 org.apache.struts.validator.ValidatorActionForm 子类:

public class AddressForm extends ValidatorActionForm {

  ...

}

对于动态 Form Bean ,在 struts-config.xml 文件中为 Form Bean 定义指定 org.apache.struts.validator.DynaValidatorActionForm 的类型,如下所示:

<form-bean name="addressForm"

          type="org.apache.struts

.validator.DynaValidatorActionForm">

  ...

</form-bean>

validation.xml 文件中,把一组验证映射到一个操作路径,而不是映射到 Form Bean 名,因为如果你定义了 Create Address Edit Address 两个操作(它们使用同一个 Form Bean ),那么每个操作都会有一个惟一的操作名,如下所示:

<action-mappings>

  <action path="/createAddress"

         type="com.jamesholmes

  .minihr.CreateAddressAction"

         name="addressForm"/>

  <action path="/editAddress"

         type="com.jamesholmes

  .minihr.EditAddressAction"

         name="addressForm"/>

 

</action-mappings>

下面的 validation.xml 文件片断显示了两组验证,它们用于同一个 Form Bean ,但却有不同的操作路径:

<formset>

  <form name="/createAddress">

    <field property="city"

          depends="required">

      <arg0 key="prompt.city"/>

    </field>

  </form>

  <form name="/editAddress">

    <field property="state"

          depends="required">

      <arg0 key="prompt.state"/>

    </field>

  </form>

</formset>

因为 Form Bean 要么属于 ValidatorActionForm 子类,要么属于 DynaValidatorActionForm 子类,所以 Validator 知道用一个操作路径代替 Form Bean 的逻辑名称来找出用于 Form Bean 的验证。


配置
validation.xml 文件

      validation.xml 文件用于声明将应用到 Form Beans 的一组验证。要验证的每个 Form Bean 在这个文件中都有自己的定义。在这个定义中,指定要应用到该 Form Bean 的各域的验证。下面是一个 validation.xml 文件的例子,说明如何定义验证:

<!DOCTYPE form-validation

PUBLIC "-//Apache Software Foundation//

       DTD Commons Validator Rules

       Configuration 1.0//EN"

       "http://jakarta.apache.org/

      commons/dtds/validator_1_0.dtd">

 

<form-validation>

  <formset>

    <form name="logonForm">

      <field property="username"

            depends="required">

        <arg0 key="prompt.username"/>

 

      </field>

      <field property="password"

            depends="required">

        <arg0 key="prompt.password"/>

      </field>

    </form>

  </formset>

</form-validation>

validation.xml 文件的第一个元素是 form-validation 。这个元素是该文件的主元素,而且只定义一次。在 form-validation 元素内定义 form-set 元素,它包括多个表单元素。一般来说,在文件中只定义一个 form-set 元素,但是如果要将验证国际化,那就要在每个地方单独使用一个 form-set 元素。

每个表单元素使用 name 属性将名称与其所包含的域验证集关联起来。 Validator 使用这个逻辑名称将这些验证映射到在 struts-config.xml 文件中定义的一个 Form Bean 。根据要验证的 Form Bean 的类型, Validator 力求将该名称与 Form Bean 的逻辑名称或操作路径相匹配。在表单元素内, field 元素定义要应用到 Form Bean 的特定域的验证。 field 元素的 property 属性对应于特定 Form Bean 中的域名。 depends 属性利用 validator-rules.xml 文件指定验证例行程序的逻辑名称,这些例行程序将应用到域验证中。


配置
ApplicationResources.properties

      Validator 使用 Struts 的资源绑定( Resource Bundle )机制将错误消息具体化。不用在框架中对错误消息进行硬编码, Validator 使你能在 ApplicationResources.properties 文件中为一个消息指定一个键值,如果验证失败则将返回该键值。 validator-rules.xml 文件中的每个验证例行程序都用 validator 标记的 msg 属性指定错误消息的键值,如下所示:

<validator name="required"

          classname="org.apache

 

.struts.validator.FieldChecks"

          method="validateRequired"

          methodParams="java.lang

.Object, org.apache.commons.validator

.ValidatorAction, org.apache.commons

.validator.Field, org.apache.struts

.action.ActionErrors, javax.servlet

.http.HttpServletRequest"

          msg="errors.required">

如果在验证例行程序运行时验证失败,则返回与 msg 属性指定的键值对应的消息。

下面的片段显示来自 ApplicationResources.properties 文件的验证出错时的默认消息集,它们由 Struts 示例应用程序提供。每个消息的键值对应于每个由 validator-rules.xml 文件中的验证例行程序所指定的消息,它们由 Struts 示例应用程序提供。

# Error messages for Validator framework validations

errors.required={0} is required.

errors.minlength={0} cannot be less than {1} characters.

errors.maxlength={0} cannot be greater than {2} characters.

errors.invalid={0} is invalid.

errors.byte={0} must be a byte.

errors.short={0} must be a short.

errors.integer={0} must be an integer.

errors.long={0} must be a long.0.   errors.float={0} must be a float.

 

errors.double={0} must be a double.

errors.date={0} is not a date.

errors.range={0} is not in the range {1} through {2}.

errors.creditcard={0} is not a valid credit card number.

errors.email={0} is an invalid e-mail address.

请注意,每条消息都有占位符,形式为 {0} {1} {2} 。在运行期间,占位符被另一个值代替,如所验证的域的名称。这一特性特别有用,它使你能够创建可被几个不同的域重复使用的通用验证错误消息。

例如,下面给出 required 验证的错误消息 errors.required

errors.required={0} is required.

当你使用 validation.xml 文件中的该 required 验证时,必须定义用于替换该错误消息中的 {0} 的值,如下所示:

<form name="auctionForm">

  <field property="bid" depends="required">

    <arg0 key="prompt.bid"/>

  </field>

</form>

错误消息最多可以有 4 个占位符: {0} {3} 。这些占位符分别称为 arg0 arg3 ,你可以通过使用 arg0~arg3 标记来指定它们。在上面的例子中, arg0 标记指定了用于替换 {0} 占位符的值。该标记的 key 属性指定来自 ApplicationResources.properties 文件的一个消息键值,它的值用于替换占位符,如下所示:

下一步

阅读
关于 Validator 的更多文章
jakarta.apache.org/commons/validator

关于 Struts Console 的更多文章
www.jamesholmes.com/struts

prompt.bid=Auction Bid

使用消息键值代替占位符的值,这一方法使你不必在 validation.xml 文件中对替换值反复硬编码。但是,如果你不想使用 Resource Bundle 的键值 / 值机制来指定占位符的值,则可以使用 arg0 标记的如下语法显式地指定占位符的值:

<arg0 key="Auction Bid" resource="false"/>

在这个例子中, resource 属性的值设为 false ,以便通知 Validator 要把该 key 属性指定的值作为占位符的值,而不要作为 ApplicationResources.properties 文件中消息的一个键值。


启用客户端验证

      Validator 除了提供了简化服务器端表单数据验证过程的框架外,它还提供了执行客户端验证时易于使用的方法。在 validator-rules.xml 文件中定义的每一个验证例行程序都可以随意指定 JavaScript 代码,这些代码可以在浏览器(客户端上的)中运行,从而执行与服务器端进行的验证相同的验证过程。在客户端进行验证时,除非所有表单都通过验证,否则这些表单不允许被提交。

为了启用客户端验证,必须在每个需要验证的 JSP 中放上 Struts HTML Tag Library (标记库)的 javascript 标记,如下所示:

<html:javascript formName="logonForm"/>

javascript 标记要求使用 formName 属性来为想要对其执行验证的表单指定 validation.xml 文件中给出的表单定义名,如下所示:

<form name="logonForm">

  <field property="username"

        depends="required">

    <arg0 key="prompt.username"/>

  </field>

  <field property="password"

        depends="required">

    <arg0 key="prompt.password"/>

  </field>

</form>

为表单定义指定的服务器端的所有验证都将在客户端运行。由于客户端验证用 JavaScript 执行,所以可以有多种方法不去执行它。要确保验证过程总是能运行,不论你是否选择启用了客户端验证, Validator 都在服务器端执行这些验证。


结论

      Validator 框架针对表单数据的验证提供了可配置的系统,从而为核心 Struts 框架添加了很多有价值的功能。通过把 Validator 框架用于你的应用程序,你可以节约时间并简化 Struts 应用程序的开发过程。



posted on 2007-01-10 01:07 java_蝈蝈 阅读(274) 评论(0)  编辑  收藏 所属分类: STRUTS

只有注册用户登录后才能发表评论。


网站导航: