在Struts 2应用中使用客户端校验非常简单,只需改变如下两个地方即可。
Ø 将输入页面的表单元素改为使用Struts 2标签来生成表单。
Ø 为该<s:form.../>元素增加validate="true"属性。
修改前面应用的regist.jsp页面,将页面代码改为如下形式。
程序清单:codes\04\4.2\clientValidate\regist.jsp
<h2>请输入您的注册信息</h2>
<s:fielderror/>
<s:form action="regist" validate="true">
<s:textfield name="name" label="用户名"/>
<s:textfield name="pass" label="密码"/>
<s:textfield name="age" label="年龄"/>
<s:textfield name="birth" label="生日"/>
<s:submit value="注册"/>
</s:form>
根据Struts 2的官方文档所说的,只要将JSP页面改成如上的形式,就应该可以完成客户端校验。但当笔者在浏览器中浏览该regist.jsp页面时,看到如图4.13所示的页面。
图4.13 使用客户端校验中出现的异常
图4.13显示了FreeMarker模板的详细出错信息。当然,在Tomcat控制台也可看到系列的异常信息。
出现这种错误的原因是因为,如果我们希望Struts 2的客户端校验能发生作用,那我们进入该regist.jsp页面之前必先经过Struts 2的核心Filter,而上面我们直接请求了regist.jsp页面,并未经过StrutsPrepareAndExecuteFilter。
前面我们介绍的应用都是直接将JSP页面放在Web应用的根路径下了,实际上这种做法与MVC思想是违背的,因为在纯粹的MVC思想中,JSP页面只是简单的视图,用户请求不应该直接向视图页面发送请求,而是应该向控制器发送请求,由控制器来调用视图页面向浏览者呈现数据。
为了避免这种情况,我们把上面应用中所有JSP页面都移到WEB-INF/content目录下,这样就可以避免浏览者直接向指定页面发送请求。接下来我们在struts.xml文件中配置一个通用的action,配置片段如下:
<!-- 可以匹配任何请求,直接转向对应的页面
例如abc请求,那么就会跳转到/WEB-INF/content/abc.jsp -->
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
增加上面的配置之后,浏览者不应该直接向regist.jsp页面发送请求,而是应该向regist发送请求,这个请求将会先经过StrutsPrepareAndExecuteFilter,然后再由该Filter forward到/WEB-INF/content/ regist.jsp页面。
此时,如果浏览者的输入不再符合校验规则,将看到如图4.14所示的页面。
图4.14 客户端校验的效果
从图4.14中可以看出,虽然使用客户端校验,却看不到弹出JavaScript的警告框,这种效果看起来与服务器端校验几乎完全相同,但读者可以仔细看图4.14中的地址栏,该页面的地址依然停留在原来的页面,并未提交到对应的Action。这就表明:上面的数据校验过程是客户端完成的。
客户端校验依然是基于JavaScript完成的,因为JavaScript脚本本身的限制,有些服务器端校验不能转换成客户端校验。也就是说,并不是所有的服务器端校验都可以转换成客户端校验。
客户端校验仅仅支持如下几种校验器。
Ø required validator(必填校验器)。
Ø requiredstring validator(必填字符串校验器)。
Ø stringlength validator(字符串长度校验器)。
Ø regex validator(表达式校验器)。
Ø email validator(邮件校验器)。
Ø url validator(网址校验器)。
Ø int validator(整数校验器)。
Ø double validator(双精度数校验器)。
客户端校验有三个值得注意的地方:
Ø Struts 2的<s:form .../>元素有一个theme属性,不要将该属性指定为simple。
Ø 浏览者不能直接访问启用客户端校验的表单页,这样会引发异常。我们可以把启用客户端校验的表单页放到WEB-INF路径下去,让浏览者访问所有资源之前都先经过它的核心Filter。
Ø 启用客户端校验的表单页面的action和namespace要分开写,例如我们向namespace为/lee,name为registPro的Action请求,应写成<s:form action="registPro" namespace= "/ee">,而不应该写成<s:form action="lee/registPro" >。提示:
|