本文我们来讨论一下Struts中的输入校验问题。我们知道,信息系统有垃圾进垃圾出的特点,为了避免垃圾数据的输入,对输入进行校验是任何信息系 统都要面对的问题。在传统的编程实践中,我们往往在需要进行校验的地方分别对它们进行校验,而实际上需要校验的东西大多都很类似,如必需的字段、日期、范 围等等。因此,应用程序中往往到处充斥着这样一些显得冗余的代码。而与此形成鲜明对照的是Struts采用Validator框架(Validator框 架现在是Jakarta Commons项目的一部分)来解决校验问题,它将校验规则代码集中到外部的且对具体的应用程序中立的.xml文件中,这样,就将那些到处出现的校验逻辑 从应用程序中分离出来,任何一个Struts应用都可以使用这个文件,同时还为校验规则的扩展提供了便利。更难能可贵的是由于Validator框架将校 验中要用到的一些消息等信息与资源绑定有机结合在一起,使得校验部分的国际化编程变得十分的便捷和自然。
Validator框架大致有如下几个主要组件:
Validators:是Validator框架调用的一个Java类,它处理那些基本的通用的校验,包括required、mask(匹配正则表达式)、最小长度、最大长度、范围、日期等
.xml配置文件:主要包括两个配置文件,一个是validator-rules.xml,另一个是validation.xml。前者的内容主要包含一些校验规则,后者则包含需要校验的一些form及其组件的集合。
资源绑定:提供(本地化)标签和消息,缺省地共享struts的资源绑定。即校验所用到的一些标签与消息都写在ApplicationResources.properity文件中。
Jsp tag:为给定的form或者action path生成JavaScript validations。
ValidatorForm:它是ActionForm的一个子类。
为了对Validator框架有一个比较直观的认识,我们还是以前面的登陆例子的输入来示范一下Validator框架的使用过程:
首先,找一个validator-rules.xml文件放在mystruts\WEB-INF目录下,下面是该文件中涉及到的required验证部分代码的清单:
- <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">
- <!--③-->
- <javascript><![CDATA[ </span> </li> <li class=""><span><span class="cdata"> function validateRequired(form) { </span> </span></li> <li class="alt"><span><span class="cdata"> var isValid = true; </span> </span></li> <li class=""><span><span class="cdata"> var focusField = null; </span> </span></li> <li class="alt"><span><span class="cdata"> var i = 0; </span> </span></li> <li class=""><span><span class="cdata"> var fields = new Array(); </span> </span></li> <li class="alt"><span><span class="cdata"> oRequired = new required(); </span> </span></li> <li class=""><span><span class="cdata"> for (x in oRequired) { </span> </span></li> <li class="alt"><span><span class="cdata"> var field = form[oRequired[x][0]]; </span> </span></li> <li class=""><span><span class="cdata"> </span> </span></li> <li class="alt"><span><span class="cdata"> if (field.type == 'text' || </span> </span></li> <li class=""><span><span class="cdata"> field.type == 'textarea' || </span> </span></li> <li class="alt"><span><span class="cdata"> field.type == 'file' || </span> </span></li> <li class=""><span><span class="cdata"> field.type == 'select-one' || </span> </span></li> <li class="alt"><span><span class="cdata"> field.type == 'radio' || </span> </span></li> <li class=""><span><span class="cdata"> field.type == 'password') { </span> </span></li> <li class="alt"><span><span class="cdata"> </span> </span></li> <li class=""><span><span class="cdata"> var value = ''; </span> </span></li> <li class="alt"><span><span class="cdata"> // get field's value </span> </span></li> <li class=""><span><span class="cdata"> if (field.type == "select-one") { </span> </span></li> <li class="alt"><span><span class="cdata"> var si = field.selectedIndex; </span> </span></li> <li class=""><span><span class="cdata"> if (si >= 0) { </span> </span></li> <li class="alt"><span><span class="cdata"> value = field.options[si].value; </span> </span></li> <li class=""><span><span class="cdata"> } </span> </span></li> <li class="alt"><span><span class="cdata"> } else { </span> </span></li> <li class=""><span><span class="cdata"> value = field.value; </span> </span></li> <li class="alt"><span><span class="cdata"> } </span> </span></li> <li class=""><span><span class="cdata"> </span> </span></li> <li class="alt"><span><span class="cdata"> if (trim(value).length == 0) { </span> </span></li> <li class=""><span><span class="cdata"> </span> </span></li> <li class="alt"><span><span class="cdata"> if (i == 0) { </span> </span></li> <li class=""><span><span class="cdata"> focusField = field; </span> </span></li> <li class="alt"><span><span class="cdata"> } </span> </span></li> <li class=""><span><span class="cdata"> fields[i++] = oRequired[x][1]; </span> </span></li> <li class="alt"><span><span class="cdata"> isValid = false; </span> </span></li> <li class=""><span><span class="cdata"> } </span> </span></li> <li class="alt"><span><span class="cdata"> } </span> </span></li> <li class=""><span><span class="cdata"> } </span> </span></li> <li class="alt"><span><span class="cdata"> if (fields.length > 0) { </span> </span></li> <li class=""><span><span class="cdata"> focusField.focus(); </span> </span></li> <li class="alt"><span><span class="cdata"> alert(fields.join('\n')); </span> </span></li> <li class=""><span><span class="cdata"> } </span> </span></li> <li class="alt"><span><span class="cdata"> return isValid; </span> </span></li> <li class=""><span><span class="cdata"> } </span> </span></li> <li class="alt"><span><span class="cdata"> </span> </span></li> <li class=""><span><span class="cdata"> // Trim whitespace from left and right sides of s. </span> </span></li> <li class="alt"><span><span class="cdata"> function trim(s) { </span> </span></li> <li class=""><span><span class="cdata"> return s.replace( /^\s*/, "" ).replace( /\s*$/, "" ); </span> </span></li> <li class="alt"><span><span class="cdata"> } </span> </span></li> <li class=""><span><span class="cdata"> </span> </span></li> <li class="alt"><span><span class="cdata"> ]>
- </javascript>
- </validator>
① 节的代码是引用一个服务器边的验证器,其对应的代码清单如下:
- public static boolean validateRequired(Object bean,
- ValidatorAction va, Field field,
- ActionErrors errors,
- HttpServletRequest request) {
- String value = null;
- if (isString(bean)) {
- value = (String) bean;
- } else {
- value = ValidatorUtil.getValueAsString(bean, field.getProperty());
- }
- if (GenericValidator.isBlankOrNull(value)) {
- errors.add(field.getKey(), Resources.getActionError(request, va, field));
- return false;
- } else {
- return true;
- }
- }
② 节是验证失败后的出错信息,要将对应这些键值的信息写入到ApplicationResources.properity文件中,常见的错误信息如下:
- # Standard error messages for validator framework checks
- 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.
③ 节的代码用于客户边的JavaScript验证
其次,在validation.xml文件中配置要验证的form极其相应的字段,下面是该文件中的代码:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation </span></li> <li class="alt"><span>//DTD Commons Validator Rules Configuration 1.0//EN"
- "http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
- <form-validation>
- <formset>
- <form name="userInfoForm">
- <field property="username"
- depends="required,mask,minlength,maxlength">
- <arg0 key="logon.jsp.prompt.username" resource="true"/>
- <arg1 name="minlength" key="${var:minlength}" resource="false"/>
- <arg1 name="maxlength" key="${var:maxlength}" resource="false"/>
- <var>
- <var-name>mask</var-name>
- <var-value>^\w</var-value>
- </var>
- <var>
- <var-name>minlength</var-name>
- <var-value>2</var-value>
- </var>
- <var>
- <var-name>maxlength</var-name>
- <var-value>16</var-value>
- </var>
- </field>
- <field property="password"
- depends="required,minlength,maxlength">
- <arg0 key="logon.jsp.prompt.password" resource="true"/>
- <arg1 name="minlength" key="${var:minlength}" resource="false"/>
- <arg1 name="maxlength" key="${var:maxlength}" resource="false"/>
- <var>
- <var-name>minlength</var-name>
- <var-value>2</var-value>
- </var>
- <var>
- <var-name>maxlength</var-name>
- <var-value>16</var-value>
- </var>
- </field>
- </form>
- </formset>
- </form-validation>
这里要注意的是:该文中的<arg0 key="logon.jsp.prompt.username" resource="true"></arg0>和<arg0 key="logon.jsp.prompt.password" resource="true"></arg0>中的键值都是取自资源绑定中的。前面还讲到了出错信息也是写入ApplicationResources.properity文件中,因此,这就为国际化提供了一个很好的基础。
再次,为了使服务器边的验证能够进行,将用到的formBean从ActionForm的子类改为ValidatorForm的子类,即:
将public class UserInfoForm extends ActionForm改为:public class UserInfoForm extends ValidatorForm
到此,进行服务器边的验证工作已经一切准备得差不多了,此时,只要完成最后步骤就可以实验服务器边的验证了。但大多数情况下,人们总希望把这些基本的简单验证放在客户边进行。
为了能进行客户边的验证,我们还要对logon.jsp文件做适当的修改。
将<ccid_nobr></ccid_nobr>
- <html:form action="/logonAction.do" focus="username">
改为
- <html:form action="/logonAction.do" focus="username"
- onsubmit="return validateUserInfoForm(this)">
在标签后加上:
- <html:javascript dynamicJavascript="true" staticJavascript="true"
- formName="userInfoForm"/>
最后,对struts的配置文件struts-config.xml作适当的修改:
1、将<ccid_nobr></ccid_nobr>
- <action input="/logon.jsp" name="userInfoForm"
- path="/logonAction" scope="session" type="action.LogonAction" validate="false" >
改为
- <action input="/logon.jsp" name="userInfoForm"
- path="/logonAction" scope="session" type="action.LogonAction" validate="true" >
其作用是要求进行校验
2、将下列代码放在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>
到此为止,我们的一切工作准备就绪,您可以享受自己的劳动成果了,试着输入各种组合的用户名和口令,看看它们的验证效果。仔细体会你会发现,服务器边的验证要更全面一些,比如对password的字符长度的验证。
发表评论
-
获取XML数据,页面显示,实现详细信息与列表的联动效果
2007-03-22 15:04 1637页面显示: 代码 //加载数据岛 ... -
在Struts中如何编写错误处理页面(errorpage.jsp)
2007-03-22 15:00 4219在Struts中对于exception出现的情况下,可以使用 ... -
Struts原理与实践(5)
2007-03-22 14:52 1082一个支持i18n的应用程序应该有如下一些特征: 1增加支持的语 ... -
Struts原理与实践(7)
2007-03-22 14:50 979在上一篇文章中介绍校验时提到客户边的校验用到了JavaScri ...
相关推荐
Struts原理与实践罗会波Struts原理与实践罗会波
Struts原理与实践(1) - Java - New - JavaEye论坛.mht
Struts原理与实践,我也不想要大家的分,我实在是没分了。谢谢
Struts原理与实践(二).rar
Struts原理与实践(一) .rar
Struts原理与实践(五).rar
Struts原理与实践(三).rar
Struts+spring+hibernate学习笔记! - Struts原理与实践
struts2 原理与实践 值得收藏
下面,我们讨论一下最后一个问题,就是读写数据库时出现乱码。 现在一些常用的数据库都支持数据库encoding,也就是说在创建数据库时可以指定它自己的字符集设置, 数据库数据以指定的编码形式存储。...
主要讲解struts原理及实践应用和指导JAVA学习阶段需要研究的开源项目struts初学者及Java进阶学者
很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:) 本节介绍了struts的基本原理,流程图看起来很直接的哦..
很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:) 本节介绍了Struts JDBC的工作原理和数据库的连接配置..
很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:) 本节介绍了Struts Web应用程序的开发步骤和一个简单例子的详细过程,...
本节介绍了struts的国际化编程问题.. 很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:)
本节介绍了采用Struts中的输入校验问题.. 很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:)
本节介绍了如何实现一个文章发布系统.. 很好的介绍struts的文章,自己就是一小节一小节学习的,每一小节都向目标迈进一步.所以将资源分了几个部分,这样大家学起来也比较有成就感.:)
Struts作为一个开放原代码的应用框架,在最近几年得到了飞速的发展,在JSP Web应用开发中应用得非常广泛,有的文献上说它已经成为JSP Web应用框架的事实上的标准。那么,究竟什么是Struts呢?