posts - 496,comments - 227,trackbacks - 0

作者:

David Winterfeldt 大卫

James Turner 詹姆斯

Rob Leland 罗伯特

翻译:

       侯思超

验证器:

0.5 版,验证器在一些 form 中就已经实现了,他最初包含在开发人员包中,后来核心代码挪到 Jakarta Commons 包中和 Struts 特别扩展中作为 Struts 1.1 的一部分。许多开发者为方便一直使用 struts 验证器,这篇文档首先概述验证器的核心功能性,然后大概介绍在 struts1.1 中的变化和新增功能。

如果你配置好验证器插件,你应该扩展 ValidatorForm 而不是 ActionForm ,以便它能加载你的 Validator 资源。他根据 struts-config.xml 文件中的 action name 属性为当前 form 的调用相应的验证器,因此在 validator-rules.xml 中的 form 元素的名称属性应该与 action name 属性值相匹配。

另外一种选择是扩展 ValidatorActionForm 而不是 ValidatorForm ValidatorActionForm 使用 struts-config.xml action path 属性,所以 path 属性的值相应的应该与 validator-rules.xml 中的 Form name 属性匹配。

一个分离的 action 可以定义给多页 form 的每个页面,而且验证规则可以与 action 关联而不是与页码,就像验证范例中的多页 form 范例那样。

国际化

validator-rules.xml 文件中 form 的验证规则可以组织为 FormSet FormSet 有与 java.util.Locale 类相应的属性:如语言 , 国家以及变量型属性,如果他们未定义, FormSet 将把它设置为默认值。一个 FormSet 也可以有关联的常量。另外还可以定义与 FormSet 同一级别的全局 global 元素,他与 FormSet 同样也有常量。

注意 :你必须在国际化的 FormSet 前声明一个没有国际化的默认 FormSet 。这样如果 Validator 没有找到 locale 时可以有一个默认版本。

       可插入验证器的默认错误信息值可以被 msg 元素覆盖。所以为 mask 验证器生成错误信息的替代方法就是使用 msg 属性,如果字段的 name 属性与验证器的 name 属性匹配,那末将使用字段的 msg 属性。

       error messages 的可以设置 arg0-arg3 等参数元素。如果没有设置 arg0-arg3 name 属性, error messages 将使用他们作为默认的构建参数值。如果设置了 name 属性,你就可以把参数指定给一特定的可插入验证器,然后这些参数将在构造错误信息时被使用。

<field

property="lastName"

depends="required,mask">

<msg

name="mask"

key="registrationForm.lastname.maskmsg"/>

<arg0 key="registrationForm.lastname.displayname"/>

<var>

<var-name>mask</var-name>

<var-value>^[a-zA-Z]*$</var-value>

</var>

</field>

默认的 arg0-arg3 元素将在消息资源中查找相应的 key ,如果资源属性设为 false ,她将把值直接传进去,而不从消息资源中查找。注意 1.1 版本中,你必须为每个模块中明确地定义在验证中用到的消息资源,否则将使用 top-level 资源。

<field

property="integer"

depends="required,integer,intRange">

<arg0 key="typeForm.integer.displayname"/>

<arg1

name="range"

key="${var:min}"

resource="false"/>

<arg2

name="range"

key="${var:max}"

resource="false"/>

<var>

<var-name>min</var-name>

<var-value>10</var-value>

</var>

<var>

<var-name>max</var-name>

<var-value>20</var-value>

</var>

</field>

常量 / 变量

全局的常量可以在全局标签中定义, FormSet/ 本地常量能在 formset 标签中创建。常量当前仅仅是代替字段的 property 属性,字段的 var 元素的 value 属性,字段的 msg 元素的 key 属性,字段的 arg0-arg3 元素的 key 属性。字段的变量也可以在 arg0-arg3 元素中被代替(例如: ${var:min} ))。替换的顺序是 FormSet/Locale 常量第一,全局的常量第二,

arg elements 变量最后。

<global>

<constant>

<constant-name>zip</constant-name>

<constant-value>^\d{5}(-\d{4})?$</constant-value>

</constant>

</global>

 

<field

property="zip"

depends="required,mask">

<arg0 key="registrationForm.zippostal.displayname"/>

<var>

<var-name>mask</var-name>

<var-value>${zip}</var-value>

</var>

</field>

验证器可以使用字段下面的变量部分来存储变量,这些变量通过字段的 getVar (String key) 方法取得。

<field

property="integer"

depends="required,integer,intRange">

<arg0 key="typeForm.integer.displayname"/>

<arg1

name="range"

key="${var:min}" resource="false"/>

<arg2

name="range"

key="${var:max}" resource="false"/>

<var>

<var-name>min</var-name>

<var-value>10</var-value>

</var>

<var>

<var-name>max</var-name>

<var-value>20</var-value>

</var>

</field>

使用 validwhen 设计复杂的验证

使用 validwhen 来设计复杂验证的一个经常的要求就是根据一个字段验证另外一个字段(比如 , 如果你要用户两次输入口令来确认值口令一致),另外一个就是表单中的一个字段只有另外一个字段有确定值的时候才是必须输入的。新的 validwhen 验证规则将很快被包含在 1.1 后的 STRUTS 版本中,她就是用来处理这种情况的。

       validwhen 规则处理单个的变量字段,叫测试。这变量的值是一个布尔的表达式,如果验证有效则它必须为真。可以包含这种变量的表达式有:

u       单引号或双引号字符串 literals

u       十进制、十六进制、八进制的 Integer literals

u       null null 和空字符串匹配,

u       其它可以用属性名引用的 form 字段 , 例如 customerAge

u       可以在外部因用得索引字段 , 例如 childLastName[2]

u       可以默认 implicit 因用得索引字段 , 例如 childLastName[], 她将作为被索引的字段使用同样的索引到数组中,

The literal * 这里指它包含当前测试字段的值,

作为例子,考虑一个包含通讯地址和邮箱字段的 form 。如果通讯地址不为空则邮箱字段是必须的 required 。你能这样定义 validwhen 规则:

<field property="emailAddress" depends="validwhen">

<arg0 key="userinfo.emailAddress.label"/>

<var>

<var-name>test</var-name>

<var-value>((sendNewsletter == null) or (*this* != null))</var-value>

</var>

</field>

上面定义的意思是:如果通讯地址是空或不空时这个字段时有效的。

这里有个稍微复杂的例子,它使用了索引字段。假定有一个表单,允许用户输入他们希望定购的部件号和数量。类 orderLine bean 的一数组被用来在称为 orderLines 的一属性保持输入项。

If you wished to verify that every line with part number also had a quantity entered, you could do it with:

如果你希望校验订单中有数量输入得每一行,你可以这样:

<field

property="quantity"

indexedListProperty="orderLines"

depends="validwhen">

<arg0 key="orderform.quantity.label"/>

<var>

<var-name>test</var-name>

<var-value>((orderLines[].partNumber == null) or (*this* != null))</var-value>

</var>

</field>

这里的意思是:如果相应的 partNumber 字段是空 , 或这字段是不空的,则这字段是有效的。

最后一个例子,想象一表单,用户必须输入他们的以英寸为单位的高度,如果他们在高度在 60 英寸以下,则出一错误。( it is an error to have checked off nbaPointGuard as a career.

<field property="nbaPointGuard" depends="validwhen">

<arg0 key="careers.nbaPointGuard.label"/>

<var>

<var-name>test</var-name>

<var-value>((heightInInches >= 60) or (*this* == null))</var-value>

</var>

</field>

 

给程序员的简单说明:

所有的比较关系必须在 parens 封装。 All comparisons must be enclosed in parens.

只有两个 itme 时可以 and or 链接。

如果比较的两 item 都可以转为整数,则使用 numeric 比较,否则使用字符串比较。

可插入验证器

验证是从 validation.xml 文件中加载的,默认的验证规则定义在 validation.xml 文件中,默认定义了 required, mask ,byte, short, int, long, float, double, date ( 没有本地支持 ), and a numeric range

" mask " 方式依赖于默认值安装要求,那意味着 "required " 可以完成,在 "'mask " 将运行以前 "required " " mask " 方式被默认包含进框架中了。任何字段如果不是 "required " 而且是空或有零长度将跳过其他验证。

如果使用了 Javascript 标签,客户端 javascript validator's javascript 属性中查找值而且产生一个有验证 form 方法的对象,要得到更多的关于 Javascript Validator 标签工作细节的详细的解释 , 参阅 html 标签 API 参考。

"'mask' " 方式让你用一正则表达式掩码验证字段,它使用 jakarta 的正规表达式包,所有的有效性规则存储在 validator-rules.xml 文件,使用的主类是 org.apache.regexp.RE

validation.xml 文件中的验证器配置范例:

<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">

<validator name="mask"

classname="org.apache.struts.validator.FieldChecks"

method="validateMask"

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.invalid">

 

定义可插入验证器

方法的参数是用逗号分隔的一些类名称列表,方法属性需要有一个符合上面的列表的签名。列表由以下组合而成:

java.lang.Object – 要验证的 Bean

org.apache.commons.validator.ValidatorAction – 当前 ValidatorAction

org.apache.commons.validator.Field – 要验证的字段

org.apache.struts.action.ActionErrors – 如果验证错误将加入 ActionError 的错误对象 javax.servlet.http.HttpServletRequest – 当前 request 对象。

javax.servlet.ServletContext – 应用的 ServletContext

org.apache.commons.validator.Validator– 当前的 org.apache.commons.validator.Validator 实例。

java.util.Locale – 当前用户的 Locale

多页面 form

字段部分有一可选的页面属性,它可以被设为整数,页上字段的所有验证小于或等于服务器端验证的当前页,页上字段的所有验证小于或等于客户端页上所有字段的验证小于或等于服务器端验证的当前页验证的当前页。一个 mutli-part 表单需要定义页面属性:

<html:hidden property="page" value="1"/>

比较两个字段

这是一个展示你怎样才能比较两个字段是否有一样的值的例子。比如“用户改变他们的口令“一般会有口令字段和一确认字段。

<validator name="twofields"

classname="com.mysite.StrutsValidator"

method="validateTwoFields"

msg="errors.twofields"/>

<field property="password" depends="required,twofields">

<arg0 key="typeForm.password.displayname"/>

<var>

<var-name>secondProperty</var-name>

<var-value>password2</var-value>

</var>

</field>

 

public static boolean validateTwoFields(

Object bean, ValidatorAction va, 

Field field, ActionErrors errors, HttpServletRequest request, 

ServletContext application) {

String value = ValidatorUtils.getValueAsString( bean,  field.getProperty());

String sProperty2 = field.getVarValue("secondProperty");

String value2 = ValidatorUtils.getValueAsString( bean,  sProperty2);

 

       if (!GenericValidator.isBlankOrNull(value)) {

try {

if (!value.equals(value2)) {

errors.add(field.getKey(),

Resources.getActionError( application, request, va, field));

                            return false;

}

} catch (Exception e) {

errors.add(field.getKey(), Resources.getActionError( application, request, va, field));

return false;

}

}

}

已知的 bug

Struts Validator 依赖于 Commons Validator 包,所以问题报告和增强需求可能在两个产品中列出。

·   Struts Validator Bugzilla Reports

·   Commons Validator Bugzilla Reports

变更和 deprecations

新建的标记属性。

<html:javascript> 标记有新的属性定义 .

使用 commons-validator.jar 中的 DTD 验证。

当前使用的验证 XML 文件是根据 commons-validator.jar 中的 DTD Struts 不在为 validator-rules.xml and validator.xml. 单独维护一个分离的 DTD ,另外 ,commons-validator 现在维护一个统一的 validator.dtd 。修改所有 validator.xml 文件的 DTD 引用为

<!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">

空字段。

当前默认在所有得基础验证类型中忽略空白的字段,如果你要求一个字段必须输入,那末在你的应用的 validator.xml 文件相应的字段定义的 depends 属性中添加 " required "

新建的范围 RANGE 方法 .

JavaScript JAVA 中都添加了 intRange & floatRange 方法。

有条件地 REQUIRED 字段 .

最大的修改是添加了基于其她字段的值的有条件地 require 验证的能力。它允许你定义逻辑如:“只有 X 字段非空的时候 Y 字段为 ’male’ 才有效”,这是实现上述逻辑的推荐方法,这种方法在 1.1 版后的第一版将实现。在 1.1 版中添加的 Requiredif 验证规则,将在新版中去掉。不过,如果你正准备使用 requiredif ,这里有一个简短的教程。

       让我们假定你有一个有 3 个字段的医药的信息表单,性别 sex ,怀孕测试 pregnancyTest ,测试结果 testResult ,如果性别为 'f' or 'F' ,则怀孕测试 pregnancyTest required ,如果 pregnancyTest 不是空,测试结果 testResult required

你的 validation.xml 文件的输入项应该是这样的:

<form name="medicalStatusForm">

<field property="pregnancyTest" depends="requiredif">

<arg0 key="medicalStatusForm.pregnancyTest.label"/>

<var>

<var-name>field[0]</var-name>

<var-value>sex</var-value>

</var>

<var>

<var-name>fieldTest[0]</var-name>

<var-value>EQUAL</var-value>

</var>

<var>

<var-name>fieldValue[0]</var-name>

<var-value>F</var-value>

</var>

<var>

<var-name>field[1]</var-name>

<var-value>sex</var-value>

</var>

<var>

<var-name>fieldTest[1]</var-name>

<var-value>EQUAL</var-value>

</var>

<var>

<var-name>fieldValue[1]</var-name>

<var-value>f</var-value>

</var>

<var>

<var-name>fieldJoin</var-name>

<var-value>OR</var-value>

</var>

</field>

<field property="testResult" depends="requiredif">

<arg0 key="medicalStatusForm.testResult.label"/>

<var>

<var-name>field[0]</var-name>

<var-value>pregnancyTest</var-value>

</var>

<var>

<var-name>fieldTest[0]</var-name>

<var-value>NOTNULL</var-value>

</var>

</field>

</form>

 

这里有一个使用索引的属性更复杂的例子,如果你的 struts-config.xml 有这下面:

<form-bean name="dependentlistForm"

type="org.apache.struts.webapp.validator.forms.ValidatorForm">

<form-property

name="dependents"

type="org.apache.struts.webapp.validator.Dependent[]" size="10"/>

<form-property name="insureDependents" type="java.lang.Boolean" initial="false"/>

</form-bean>

这里 dependentlistForm bean lastName firstName dob coverageType 四个属性,你可以这样定义一验证规则:

<form name="dependentlistForm">

<field

property="firstName" indexedListProperty="dependents" depends="requiredif">

<arg0 key="dependentlistForm.firstName.label"/>

<var>

<var-name>field[0]</var-name>

<var-value>lastName</var-value>

</var>

<var>

<var-name>fieldIndexed[0]</var-name>

<var-value>true</var-value>

</var>

<var>

<var-name>fieldTest[0]</var-name>

<var-value>NOTNULL</var-value>

</var>

</field>

 

<field

property="dob" indexedListProperty="dependents" depends="requiredif,date">

<arg0 key="dependentlistForm.dob.label"/>

<var>

<var-name>field[0]</var-name>

<var-value>lastName</var-value>

</var>

<var>

<var-name>fieldIndexed[0]</var-name>

<var-value>true</var-value>

</var>

<var>

<var-name>fieldTest[0]</var-name>

<var-value>NOTNULL</var-value>

</var>

</field>

 

<field

property="coverageType" indexedListProperty="dependents" depends="requiredif">

<arg0 key="dependentlistForm.coverageType.label"/>

<var>

<var-name>field[0]</var-name>

<var-value>lastName</var-value>

</var>

<var>

<var-name>fieldIndexed[0]</var-name>

<var-value>true</var-value>

</var>

<var>

<var-name>fieldTest[0]</var-name>

<var-value>NOTNULL</var-value>

</var>

<var>

<var-name>field[1]</var-name>

<var-value>insureDependents</var-value>

</var>

<var>

<var-name>fieldTest[1]</var-name>

<var-value>EQUAL</var-value>

</var>

<var>

<var-name>fieldValue[1]</var-name>

<var-value>true</var-value>

</var>

<var>

<var-name>fieldJoin</var-name>

<var-value>AND</var-value>

</var>

</field>

</form>

这里的意思是:

如果 lastName 字段是非空的, firstName 字段 required 。因为字段 Indexed 为真,这它意味着 lastName indexed 必须与 firstName 的索引的一样, dob 同理,除非 date 不为空。

如果 lastName 用样索引时的值不空 , 而且非索引字段 insureDependents 为真,则 coverageType only require

你可以对字段在 [n] 中使用任意数字,唯一的限制是他们必须都是 AND OR, 你无法混合使用。

Deprecation

u       JavaScript Java range 方法 .

u       StrutsValidator &StrutsValidatorUtil 类中的 Deprecation 方法

验证器 api 指南

一个简明的 Struts验证器API指南 可以帮助你开始。

验证器资源

Struts Validator: Validating Two Fields Match 作者Matt Raible。(两个字段匹配验证)关于使用方法的文章。(范例部分为翻译此文内容)

DynaForms and the Validator 作者James Turner and Kevin Bedell。 Struts Kickstart 的其中一章(动态form和验证器),可以自由下载PDF).

Validating user input 作者 David Winterfeldt and Ted Husted。 Struts in Action 的其中一章,可以自由下载(PDF)。


使用方法

作者:

丑陋 && Snowtears :经过 2 周的不懈努力,阅读了大量的资料,终于对 Validator 有了个初步的认识,整理了一下,浅浅的谈了谈写法,希望能有一定的帮助,其中肯定有许多说的不对不准确的地方,还请多指教 real_herozx@163.net

       王艺:

       根据以上两位的文章正理而成

配置 ruts-config.xml

1、             添加 ApplicationResources 配置文件。

如:

<!-- ========== Message Resources Definitions =========================== -->

<message-resources parameter="com.dc.sibss.om.struts.ApplicationResources" />

其中 com.sibss.om.struts.ApplicationResources" 的部分是 资源文件 的路径,此文件的作用是提供错误信息的非编程定制化和多语言支持。如果我们使用中文平台操作系统,则默认情况下将首先查找 ApplicationResource_zh_CN.properties 文件,然后是 ApplicationResources_zh.properties ,如果前两个文件没有被找到则将查找 ApplicationResources.properties 文件。

为了能够在页面上显示错误提示信息,我们还需要将以下内容添加到 ApplicationResources.properties 文件的末尾:

              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 an byte.

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

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

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

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

errors.double={0} must be an 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.

以上仅是 struts 现在支持的错误类型的错误提示信息,如果你自定义了新类型的错误验证,则还需要在此加上你自己的内容。

以上内容中的 {0} 指的是错误提交的参数。比如:当你需要页面上的“用户名”不能为空时(也就是上面的 errors.required ),这个 {0} 就代表“用户名”,所以如果你没有填写用户名将抛出如下错误:

       用户名 is required. (你可以根据需要修改称中文)

我们可能已经注意到了,既然错误提示信息需要配置,那么上例中“用户名”系统是如何得到的呢?没错!也是通过修改此配置文件,内容如下:

       visitCust.error.name.required=<br> 用户名

这样当“用户名”为空时, struts 后台程序将联合以上两处定义显示错误信息。

另外,上面的“ visitCust.error.name.required ”是在 Validation.xml 配置验证内容时指定的。 具体见以下介绍

注意:一般情况下,你的系统只需要一个 ApplicationResources 文件,所以开发组的成员不要添加自己的 resource 文件。只有在你的项目分组开发时才需要使用多个 ApplicationResources 文件,但是,同时你的 struts-config.xml 文件也会有相同的数量对应。

2、             struts-config.xml 文件中加入 validator 插件:

加入这个插件后你的应用就具备使用 Validator 的环境,如:

<!-- ========== Plug Ins Configuration ================================== -->

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

<set-property value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" property="pathnames" />

</plug-in>

这里如果是想使用多个 ***.xml 文件的话, value 部分写法如下 value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml, /WEB-INF/validation1.xml , /WEB-INF/validation2.xml "

<action-mappings> 里,定义需要验证的画面对应的 Action 的时候要加上 validate="true"

四种使用方法

1、             Javascript 在客户端进行验证

配置:在需要验证的 JSP 文件中写入

<html:form action="/XXX" onsubmit="return validateXXXX(this);">

这里的 XXX 是与要进行验证的 forward name validateXXXX (this); 里面的 XXXX 是需要进行验证的 ActionForm 名。

<html:javascript formName="mytestForm"/>

validation.xml 文件中写入验证代码就可以进行基本的验证了。这种方法是在客户端进行验证,客户端可以看到 JAVASCRIPT 部分的全代码。安全性不高

2、             ValidatorForm validate 方法

1 validate ()方法: 使自己的 ActionForm 继承 ValidatorForm 类,在里面编写自己的方法:

public ActionErrors validate (ActionMapping mapping,HttpServletRequest request) {

ActionErrors errors = new ActionErrors();

。。。。。。

if ( mytext.equals("aaa") ) {

//my exampleerrors.add("mytext",new ActionError("mytext.error"));

}

。。。。。。

return errors;

}

此时,如果写了这个方法,就会屏蔽掉在 Validation.xml 中定义的验证部分,换句话说就是系统运行时, Validation.xml 里对应此 ActionForm 的定义的错误验证部分不实行,如果不写这个方法的话,系统运行时会进行 Validation.xml 里对应此 ActionForm 的定义的错误验证部分的操作。此类方法是在服务器端进行验证,验证部分代码客户端不可见。

2 、创建你的 ActionForm 并让它继承 org.apache.struts.validator.ValidatorForm 类。创建你的 Action 实现,并和上面定义的 ActionForm 关联。这里需要注意的是,在定义此 Action 时一定将 validate 属性设置为 true ,并且在你定义的 ActionForm 中不要实现它的 validate 方法――这就意味着你将使用 ValidatorForm validate 方法,这样才能保证你的错误验证正常进行。 配置 validation.xml 文件。基本内容如下:

<form-validation>

<!-- ========== Default Language Form Definitions ===================== -->

    <formset>

              <form name="custGNewForm"> 需要验证页面上 form 的名字

                     <field property="certifiCode" 需要校验的属性

                                   depends="required,maxlength"> 校验内容

                            <arg0 key="prompt.certifiCode"/>ApplicationResource 文件中对应

                            <arg1 key="${var:maxlength}" name="maxlength" resouce="false"/>

                            <var> 确定最长限制的长度

                                   <var-name>maxlength</var-name>

                                   <var-value>20</var-value>

                            </var>

                     </field>

注意:此处的 arg0 arg1 就代表了 ApplicationResources 文件中使用“ {} ”括起来的参数。比如:

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

定义了三个参数,所以你这里也要定义 <arg0> <arg1> <arg2> 三个参数才能完整的显示错误信息。

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

定义了 0 2 两个参数,所以你就需要定义 <arg0> <arg2> 两个参数。

                     <field        property="userName"

                                   depends="required,maxlength">

                            <arg0 key="prompt.userName"/>

                            <arg2 key="${var:maxlength}" name="maxlength" resouce="false"/>

                            <var>

                                   <var-name>maxlength</var-name>

                                   <var-value>80</var-value>

                            </var>

                     </field>

                     <field property="email"

                    depends="email">

                <arg0 key="prompt.email"/>

            </field>

              </form>

              <form name="custGNewCheckForm">

                     <field       property="certifiCode"

                                   depends="required">

                            <arg0 key="prompt.certifiCode"/>

                     </field>

              </form>

    </formset>

</form-validation>

在校验页面的 <body> 前添加如下内容: <html:errors/>

3、             DynaValidatorForm

不需要再写对应的 ActionForm ,只需在 struts-config.xml 里把自己的 ActionForm 进行配置:

<form-bean name="testForm" type="org.apache.struts.validator. DynaValidatorForm">

       <form-property name="mytext" type="java.lang.String"/>

<form-property name="mytextarea" type="java.lang.String"/>

       <form-property name="mydatetext" type="java.lang.String"/>

</form-bean>

form-property 里设置相应的项目,比如说 mytext mytextarea 什么的,执行的时候会动态生成 ActionForm ,再在 validation.xml 里写入所希望的验证代码,就可以了。 JSP 文件里不需要写入任何东西,验证也是在服务器端进行,验证部分代码在 JSP 中不可见。

4、             组合验证

如果使用动态验证 DynaValidatorForm 的话,不许编写自己的 对应的 ActionForm ,相应的特殊验证会受到相当程度的限制。这个时候,需要将特殊验证部分写入对应的 Action

if(mytext.equals("aaa")){//My Example

ActionErrors errors = new ActionErrors();

errors.add("***",new ActionError("***.error"));      

saveErrors(request,errors);

return (mapping.findForward("false"));

}

就可以实现特殊验证了。

 

       实际上你的 FORM 还可以继承 ValidatorActionForm DynaValidatorActionForm ,这两种与他们对应的 ValidatorForm DynaValidatorForm 的唯一区别正如开篇就讲到的:在 struts-config.xml 中查找对应的 FORM 类时,前者根据 ACTION PATH 值,而后者使用 NAME 值。

范例:

Struts 验证器:验证两个字段匹配

在使用指南中,有一节讲述怎样创建验证器来验证两个字段匹配,我用这个服务器端验证器(象例子中显示的那样)做口令,确定口令验证。这个已经可以正常工作了;但我还想用客户端的 javascript 验证器来试一试。我写了自己的程序来比较两个字段,但他们和推荐给你的那个不同( from validator-rules.xml )。所以昨天,我补充了怎样添加 JavaScript 方法到 validator-rules.xml 这里就是怎样配置的的整个过程(大部分在使用指南中已经包含了,保存 JavaScript )。

怎样添加两个字段的验证器

Step 1: 生成一个包含 validateTwoFields 方法的 类。在我的代码重,我的类定义为 ValidationUtil ,他有下列方法:

 

public static boolean validateTwoFields(

Object bean,

ValidatorAction va,                                       

Field field,

ActionErrors errors,

HttpServletRequest request) {

 

    String value = ValidatorUtil.getValueAsString(bean, field.getProperty());

    String sProperty2 = field.getVarValue("secondProperty");

String value2 = ValidatorUtil.getValueAsString(bean, sProperty2);

 

    if (!GenericValidator.isBlankOrNull(value)) {

        try {

            if (!value.equals(value2)) {

                errors.add(field.getKey(),

                           Resources.getActionError(request, va, field));

 

                return false;

            }

        } catch (Exception e) {

            errors.add(field.getKey(),

                       Resources.getActionError(request, va, field));

 

            return false;

        }

    }

 

    return true;

}

Step 2: 编辑 validator-rules.xml ,加入 "twofields" 规则。

<validator name="twofields" classname="org.appfuse.webapp.util.ValidationUtil"

method="validateTwoFields"

    methodParams="java.lang.Object,

                  org.apache.commons.validator.ValidatorAction,

                  org.apache.commons.validator.Field,

                  org.apache.struts.action.ActionErrors,

                  javax.servlet.http.HttpServletRequest"

   depends="required" msg="errors.twofields">

    <javascript><![CDATA[

        function validateTwoFields(form) {

            var bValid = true;

            var focusField = null;

            var i = 0;

            var fields = new Array();

            oTwoFields = new twofields();

            for (x in oTwoFields) {

                var field = form[oTwoFields[x][0]];

                var secondField = form[oTwoFields[x][2]("secondProperty")];

           

                if (field.type == 'text' ||

                    field.type == 'textarea' ||

                    field.type == 'select-one' ||

                    field.type == 'radio' ||

                    field.type == 'password') {

           

                    var value;

                    var secondValue;

                    // get field's value

                    if (field.type == "select-one") {

                        var si = field.selectedIndex;

                         value = field.options[si].value;

                        secondValue = secondField.options[si].value;

                    } else {

                        value = field.value;

                        secondValue = secondField.value;

                    }

               

                    if (value != secondValue) {

                   

                        if (i == 0) {

                            focusField = field;

                        }

                        fields[i++] = oTwoFields[x][1];

                        bValid = false;

                    }

                }

            }

           

            if (fields.length > 0) {

                focusField.focus();

                alert(fields.join('\n'));

            }

           

            return bValid;

        }]]></javascript>

</validator>

Step 3: validation.xml 为你的表单配置验证:

<field property="password" depends="required,twofields">

  <msg name="required" key="errors.required"/>

  <msg name="twofields" key="errors.twofields"/>

  <arg0 key="userForm.password"/>

  <arg1 key="userForm.confirmPassword"/>

  <var>

    <var-name>secondProperty</var-name>

    <var-value>confirmPassword</var-value>

  </var>

</field>

这里 errors.twofields 字段 '{0}' 必须与字段 '{1}' 的值相同。第三步的一个可选的工作就时使用 XDoclet 来生成 validation.xml requires (1) 配置 XDoclet ( 当然 ) (2) 在你的表单中添加添加一些 @struts 标签 setPassword 方法

/**

 * Returns the password.

 * @return String

 *

 * @struts.validator type="required" msgkey="errors.required"

 * @struts.validator type="twofields" msgkey="errors.twofields"

 * @struts.validator-args arg1resource="userForm.password"

 * @struts.validator-args arg1resource="userForm.confirmPassword"

 * @struts.validator-var name="secondProperty" value="confirmPassword"

 */

public String setPassword() {

       return password;

}

我昨天已经把这个作为建议发送给struts-dev邮件列表, 但还没有收到任何消息。


posted on 2006-08-17 19:32 SIMONE 阅读(525) 评论(0)  编辑  收藏 所属分类: struts

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


网站导航: