配置
Struts Validation
框架
相信正在阅读本文的读者都是对
struts
有一定经验的,对于
struts
到哪去下载、如何安装配置就不必笔者多言。此处仅仅只讨论
struts validation
框架的安装和配置。通常,我们有
2
种方法来进行这个过程。
-
方法一:
从
struts
自带的
webapps
目录下解压
struts-balnk.war
到项目的
web
工程目录。这是最简单创建
struts
工程的方式,在这个工程中就已经包含了一个
struts
应用的所有需要的开发包和这些包的基本配置,自然也包含了其中的
validation
框架。它非常适合在项目的初创阶段,我们所需做的就是在这个空白工程中填点什么就可以了。
-
方法二:
对于已经存在的
struts
工程,如何添加
valiadation
框架支持所需的步骤也非常简单。
1.
首先在
struts-config.xml
中添加以下内容
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
2.
然后在
web-inf
目录中创建
2
个文件
validator-rules.xml
,
validation.xml
。(这
2
个文件也可从
struts-balnk.war
中获取)。
3.
复制
validation
框架所需要的类包到
web-inf/lib
下,这些类包是:
common-validator.jar
。
这样,我们就可以使用
struts
的
validation
框架了。
使用
validation
框架
问题
这是一个简单的用户管理程序,使用者可以对用户信息进行相应的
CRUD
操作(增查改删)。其中用户信息包含用户名称、用户地址、用户描述、用户密码。对于以上的各种操作,约束如下:
-
增加和修改:用户名称、用户地址、用户密码、用户密码确认为必填项,同时密码和确认密码
2
个域的值必须一致。
-
删除和查询:用户名称为必填项。
解决和使用步骤
1.
创建
struts
项目的基本环境。
2.
创建相应的页面,确定页面流程(
page flow
)。
3.
创建相应的
formbean
:
²
strut1.1
版本解决办法:
为了简单起见使用
DynaActionForm
。又由于使用了
validation
框架,此处使用
DynaValidatorForm
。
struts-config.xm
的内容:
<form-bean name="editForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="id" type="java.lang.Integer"/>
<form-property name="name" type="java.lang.String"/>
<form-property name="pwd1" type="java.lang.String"/>
<form-property name="pwd2" type="java.lang.String"/>
<form-property name="address" type="java.lang.String"/>
<form-property name="desc" type="java.lang.String"/>
</form-bean>
然后,修改
web-inf
目录下的
validation.xml
文件内容,其中
form
的名字和各域的名字必须和
struts-config.xml
中一致:
<form name="/editForm ">
<field property="name" depends="required">
<arg0 key="editForm.name"/>
</field>
<field property="pwd1" depends="required,mask">
<arg0 key="editForm.password"/>
<var>
<var-name>mask</var-name>
<var-value>^[0-9a-zA-Z]*$</var-value>
</var>
</field>
<field property="pwd2" depends="required,mask">
<arg0 key="editForm.password"/>
<var>
<var-name>mask</var-name>
<var-value>^[0-9a-zA-Z]*$</var-value>
</var>
</field>
<field property="address" depends="required ">
<arg0 key="editForm.address"/>
</field>
</form>
4.
创建相应的
Action
,同时
Action
的
validate
属性置为
true
,以启用
validation
框架。
5.
书写
ApplicationResources.properties
,添加错误信息。
²
struts1.1
errors.required={0} is required.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} 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.
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 an invalid credit card number.
errors.email={0} is an invalid e-mail address.
editForm.name= name.
editForm.password= password.
editForm.address= address
6.
在相应的
jsp
中添加
<html:errors property="age"/>
从整个使用过程来看,就验证部分而言,使用
struts1.1
的开发效率大大的得到了提高,而且通过
validator-rules.xml
使验证方法能被不同的
formbean
复用,而且可维护性也大大的得到提高。通过
mask
,使得单个页面域的验证非常灵活。
但是细心的读者可能也发现了这个验证文件仅仅指明
2
个
password
域是必填的,但并没有满足他们必须是相等的这种情形的判断,对于这一点,我们可使用自定义的
validator
并将它添加到
validator-rules.xml
文件中来完成。
创建自定义的
validator
对于
validator
的创建,可以归结为
3
步:
1.
创建
validator
类,
validator
必须包含一个以
validate
开始的方法,并且它的函数签名必须如下:
validateXXX(java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field, org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest, javax.servlet.ServletContext)
在本例中,自定义的
Validator
如下(摘至
Struts
提供的例子,用来提供
2
个域的相等性检查):
public class CustomValidator {
public CustomValidator() {
super();
}
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;
}
}
2.
添加到
validator-rules.xml
文件中:
<validator name="twofields" classname="examples.validator.CustomValidator"
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"
msg="errors.twofields" />
在对应的属性文件中添加对应的消息(
errors.twofiled
)。
3.
在
validation.xml
中使用:
<field property="pwd1" depends="required,twofields">
<arg0 key="editForm.password" />
<arg1 name="twofields" key=" editForm.password2" />
<var>
<var-name>secondProperty</var-name>
<var-value>pwd2</var-value>
</var>
</field>
通过自定义
validator
,
validation
框架的可扩展性大大的得到提高。而且也使得不同的验证方法能够很好的得到复用
javascript
支持
在
web
应用中,使用
javascript
的机会非常多。虽然不少书上提及客户有可能从浏览器关闭
js
的执行,但是要想完全的不使用它,目前看来好像还不行。比如一些复杂的
UI
是必须通过
js
来实现的(如下拉式菜单等等)。那么
validation
框架支不支持客户端的
js
验证呢?
答案是:当然。具体做法是:
-
在页面
html:form
标签内部添加
onsubmit="return validateEditForm(this);"
(具体的语法:
validate+
在
validation.xml
文件中定义的
form
的名字);如:
<html:form action="<%=action%>" method="post" onsubmit="return validateEditForm(this);">
-
在
html:form
内部块中添加:
<html:javascript formName="editForm"/>
如此
2
步即可。虽然,
validation
框架非常简单易用,但是还是有需要注意的地方。
使用注意
1.
使用
validation
框架后,
form
必须从
ValidatorForm
中派生,同时必须在你的
validate
方法中先调用基类的
validate
方法。对于使用
Dyna
开头的方法来创建
formbean
的读者,你也必须改为以
dyna
开头含有
validator
的
form
。
2.
注意
DynaValidatorForm
(
ValidatorForm
)和
DynaValidatorActionForm
(
ValidatorActionForm
)的区别。刚开始时从帮助中没看明白这
2
者的区别,后来从网上一篇文章中得到了用法的区别。前者主要的视角是
formbean
,而后者的视角是
action
。
当
formbean
被不同的
action
使用时,对于不同的
action
而言,使用的
formbean
的属性集合有大有小。此时如果仍然以
formbean
为主体,会造成其他
action
的不正常使用。因此,
struts
中提出了
DynaValidatorActionForm
(
ValidatorActionForm
)。此时在
validation.xml
中的
form
标签的
name
属性改为
action
的
path
属性,又由于
action
中有
attribute
和
name
属性,
validation
框架就可根据这个
action
得到对应的
formbean
。例子:
<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>
3.
与
DispatchAction
的配合。
Struts1.1
的
DispatchAction
使得相关的
Action
的关系紧密,大大减少了应用中
Action
的个数,但是随之而来也带来了使用
Validation
框架的不便,不能不说是一个遗憾。读者也许认为这种情况可以使用第
2
条的解决方案来解决,即采用
DyanValidatorActionForm
,然后在
Validation.xml
文件中
form
的名称使用不同的
Actiond
的
path
,即在
validation.xml
中使用:
<form name="/user.do?method=doAdd">
、
<form name="/user.do?method=doLoad">
。然而,在目前的版本中
Validation
框架并不支持这种辨认。一种绕过这个情况的方法是,针对同一个
Action
实现类在
Struts-config.xml
文件中定义多个
Action
的
path
,在不需要进行验证的地方将
Action
的
validate
属性置为
false
。即:
struts-config.xml
:
<action attribute="editForm" path="/user" name="editForm" input="/editUser.jsp"
parameter="method" scope="request" type="foxgem.struts.UserDispatchAction"
validate="true">
<forward name="load" path="/editUser.jsp"/>
<forward name="action" path="/userquery.do?pageId=1"/>
</action>
<action attribute="editForm" path="/loaduser" name="editForm" input="/editUser.jsp"
parameter="method" scope="request" type="foxgem.struts.UserDispatchAction"
validate="false">
<forward name="load" path="/editUser.jsp"/>
<forward name="action" path="/userquery.do?pageId=1"/>
</action>
然后在
validation.xml
文件中使用
2
的方法。
结束语
总的说来,
validation
框架大大的提高了页面验证的开发效率,更吸引人的是这些验证方法可通过自定义的
validator
来得到复用。使得这些验证代码更加集中,可维护性得到加强。当然随着项目的进行,
validation.xml
和
validator-rules.xml
会随之增长,这部分的维护工作加重了。
同时,由于不能非常好的和
DispatchAction
一起协作,也使得大量使用
DispatchAction
的项目不能非常好的使用它。建议大量使用
DispatchAction
和页面验证非常复杂多变的项目可以暂时按原来的方法来验证,不使用
validation
框架。
至于
validation
框架的其他详细信息,请参见
struts
的文档,在此不再赘述。
关于作者
胡键,西安交通大学工学硕士,热衷于
j2ee/.net
技术,是
OpenSource
的忠实拥护者。目前与友人创建西安烁程软件有限公司。公司主要致力于
java web
应用的开发,已有多个项目在能源、电力和交通行业得到应用。可以通过
james.hu@chinacodeline.com
与他取得联系。