Let's go inside

this blog is deprecated as a result of laziness.
posts - 59, comments - 2, trackbacks - 0, articles - 0

Struts Validation框架浅尝

Posted on 2006-08-28 08:59 Earth 阅读(763) 评论(0)  编辑  收藏 所属分类: Java转载

配置 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 与他取得联系。


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


网站导航: