在之前的校验案例中我们使用了validator框架中的”required、minLength、maxLength”这几种校验规则,对于这些规则我们知道都配置在validator-rules.xml文件中了,纵观里面的规则,我们可发现还有很多其它的校验规则,其中“mask”可以校验正则表达式,“date”可校验日期格式,“email”可校验邮件的格式,可见这框架的强大之处,我们使用”date”和”email”分别来校验表单中的日期和邮件输入的格式,首先在表单中增加两个这样的输入域,然后在userForm中对应的增加字段,然后在校验文件中增加如下两个字段的校验:
<field property="email" depends="email"> <arg key="prompt.email"/> </field>
<field property="birthday" depends="date"> <arg key="prompt.date"/> <var> <var-name>datePattern</var-name> <var-value>yyyy-MM-dd</var-value> </var> </field> |
校验邮件格式跟之前的几个校验没啥区别,但是日期格式的校验时我们得设置日期匹配的类型变量,这样就能达到日期和邮件的校验了,对于这种自身的校验之外,还有一种校验,如确认密码和密码是否是相同的这样的校验则不是单纯校验本身了,而是跟别的进行一个对比,这时另一种校验规则出现了,“validwhen”,它是专门来校验像这种复杂类型的校验规则,所以我们在表单中再添加一个文本域叫password2,然后在formbean中添加相应的字段,最后我们在校验文件中进行配置,用这种校验时得注意,因为它的消息KEY和”required”校验器的是一样的,都是“errors.required”,所以这时我们同时用上这两个校验规则,从中来说明一个问题,这个字段的校验如下:
<field property="password2" depends="required,validwhen"> <msg key="errors.password2" name="validwhen"/> <arg key="prompt.password2"/> <var> <var-name>test</var-name> <var-value>(*this* == password)</var-value> </var> </field> |
在使用“validwhen”校验器进行校验时我们得设置test变量,在使用这个校验器时我们还面临一个问题,之前也说过了,它的消息KEY跟”required”是一样的,当对一个字段进行校验时这两个校验规则并存时就应该采取相应的措施来避免冲突的产生,我们让required还保持默认,所以我们用arg来进行参数的配置,而validwhen则不能采用默认了,我们应该改变它的消息KEY,这时我们可用msg标签来进行替换,name指的是哪个校验器发生时,key则表示会用指定的消息KEY,这是使用这个校验器的一个需要注意的问题。
可能在实际中我们会遇到如下情况:如果两个Action关联的是同一个ActionForm,但它们的校检规则可能不一样,在ActionForm中该如何编写validate方法?例如,增加用户和修改用户时可使用同一个ActionForm,但是修改用户不需要校验密码:
<form name=”userForm” type=”….”/> <action path=”/addUser” name=”userForm” type=”…..”/> <action path=”/editUser” name=”userForm” type=”….”/> |
像这样的需求我们怎么来实现呢?ValidatorActionForm就是用来解决这样的问题的,我们让我们的Formbean来继承它而代替ValidatorForm,然后对于这两个Action有不同的校验规则,所以我们得在validation.xml中配置两套校验规则,而校验规则的命名是以action的path路径为名,这样对于每个Action请求就会根据请求名称来到validator.xml中找到不同的校验规则,重要原因还是ValidatorActionForm这个类起的作用,原来我们用ValidatorForm时是根据Action所关联的Fomrbean的名称来进行校验规则匹配的,而这个类则是根据Action的path路径来找相应的校验规则的,所以这样就解决了这种需求了,validator.xml中的模拟写法就如下:
<form-validation>
<formset> <form name="/editUser"> <field property="name" depends="required"> <arg key="prompt.username"/> </field> ... </form> <form name="/addUser"> <field property="name" depends="required"> <arg key="prompt.username"/> </field> ... </form> </formset> |
在学struts的时候我们知道还有一种动态ActionForm,那如果是这种情况下用validator框架来对进行校验又该如何做呢?struts又提供了一个类专门来解决这样的问题的,叫“DynaValidatorForm”,我们在struts-config.xml中把动态ActionForm配成如下:
<form-bean name="userForm" type="org.apache.struts.validator.DynaValidatorForm"> <form-property name="name" type="java.lang.String"/> <form-property name="password" type="java.lang.String"/> </form-bean>
|
这时我们在validation.xml针对这个formbean配置一套校验规则既可实现校验,其实跟自己手动编写的formbean一样,对于多个Action引用同一个动态formbean但其校验规则不同的情况,我们将动态formbean配成DynaValidatorActionForm,既可完成这样的需求,原理跟ValidatorActionForm一样。
此对对于用JavaScript校验功能用这个校验框架也能办到,而不用我们自己在客户端进行代码编写,要用使用Validator的JavaScript校验功能,要在JSP页面中使用struts的<html:javascript formName=”xxx”>标签,其中的xxx是某个校验域的名称,对于我们这个例子则是userForm,然后在需要验证的表单的onsubmit属性中调用“return validateXxx()”方法,其中validateXxx方法可能通过<html:javascript>的method属性来改变,默认是配置的formName的名称,于是我们在用户注册JSP中加入如下语句来生成Javascript校验代码:
<html:javascript formName="userForm"/> |
这时我们访问此页面,然后查看其源代码就会发现生成validateUserForm()的校验方法:
假如我们想改变生成的方法名称,可用method属性来进行改变:
<html:javascript formName="userForm" method=”xxx”/>
这里我们采用默认的方法,知道这个方法之后,然后我们在表单的submit方法中进行访问:
<html:form action="/RegUser" οnsubmit="return validateUserForm(this);">
….
</html:form>
然后表单就具有JavaScript校验功能了:
但是关于struts validator校验器生成的javascript校验功能,还有一个问题,给合这个例子来看,当我们什么都不填写时只会弹出一个对话框,但是如果密码长度很短,就会弹出两个对话框,效果如下:
从这两个对话框可以看出规律,就是对于多个表单字段元素违背的同一个校验规则的信息都显示在一个对话框,其实没必要一下显示多个对话框,我们希望只弹出第一个对话框,只有修完第一个对话框的问题后才单独弹出第二个对话框的内容,这就涉及到Javascript的短路功能了,而要实现短路功能我们只要在struts配置文件中配validator插件中将”stopOnFirstError”属性设为”true”既可,如:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> <set-property property="stopOnFirstError" value="true"/> </plug-in> |
这样就只会弹出一个对话框来显示同组的校验错误信息,等修改好这一组后再会弹出第二个对话框,显示效果:
如果要为ValidatorActionForm对应的表单生成前台的javaScript校验代码,可以使用类似如下的代码:<html:javascript formName="/addUser"/>,其中的formName与校验域的名字完全一样,生成的javascript方法则是按formBean的名称来的。