图1-3显示了客户端验证中涉及的组件。
在图1-3中,客户端数据验证代码嵌在HTML页面中。获取这个HTML页面时,验证代码会从服务器传输到客户端。然后用户在HTML表单中输入数据。当用户点击按钮提交表单时,将执行客户端验证代码。如果检测到错误,数据就不会传输到服务器。
此时要求用户修正输入中的错误,并重新提交表单。只有当所有客户端验证都成功完成时,数据才会传输到服务器。
图1-3客户端验证的组成
客户端脚本语言
客户端验证代码用一种解释型脚本语言编写。这种脚本语言的解释器嵌在浏览器中。以下两种脚本语言最为常用:
q JavaScript(有时称为ECMAScript)。
q VBScript。
ECMAScript是一种标准脚本语言,它实际上是JavaScript的一个子集。用ECMAScript子集编写的脚本代码可移植性最强,能够在不同浏览器之间顺利移植。
VBScript的语法与Microsoft的Visual Basic编程语言很相似。只有Microsoft Internet Explorer浏览器才支持VBScript,而Netscape和Microsoft浏览器都能支持JavaScript。如果希望客户端验证代码在两种环境下都能用,就应该使用JavaScript来编写。
以下实验展示了如何使用JavaScript来完成客户端数据验证。
实验:客户端验证
这是一个用户向网上商店添加商品信息的例子。表单由JSP生成与处理,并使用客户端JavaScript代码来完成客户端数据验证。这个例子要用到ch12.war[2]文件。
运行Tomcat 5服务器,并在其上部署ch12.war;有关部署方法,请参见《JSP程序设计》的第1章。
打开浏览器,访问以下URL:
http://localhost:8080/ch12/example1/index.jsp
这样会得到一个类似于图1-4所示的表单,让你输入商品信息。

图1-4 提供客户端数据验证的商品信息输入表单
在这个表单中输入以下值:
q 在sku 字段中,输入3212a。
q 在name 字段中,输入2 Beginning JavaServer Pages。
q 在desc 字段中,输入Excellent book to learn JSP with。
q 在price 字段中,输入M39。
上述输入值是特别设计的,故意包含有几个错误,应该能被验证代码捕获到。
点击Add Product(添加商品)按钮,就会启动客户端验证代码,从而检测到错误,你会看到一个弹出的对话框,如图1-5所示。

图1-5 指出数据输入错误的弹出对话框
点击OK按钮,关闭这个对话框。这些错误会在表单中突出显示。此时不会向服务器发送任何数据。现在你的表单应该如图1-6所示。

图1-6 客户端数据验证检测到的输入错误
图1-6显示出,检测到了3个错误。第一个是sku中输入的值有错误。sku格式要求只能包含数字,而不允许有任何字符。为了修正这个错误,可以删除最后面的字符a。再点击Add Product按钮,得到如图1-7所示的界面。

图1-7 修正了一个输入错误后显示的表单
注意在图1-7中,sku已经合法,现在只有两个错误了。可以进行如下修正:
① 删除name字段中最前面的2,因为这个字段必须以字母开头。
② 删除price字段中最前面的M,因为这个字段只能包含数字型的美元值。
再点击Add Product按钮。
这一次,所有值都通过了验证,表单数据最终提交到服务器。表单数据将由服务器端JSP处理。该JSP只是显示出表单中各个字段的值。所得到的结果如图1-8所示。

图1-8 修正了所有错误后,成功地输入了商品数据
实验解析
这个例子使用了一个前端控制器页面index.jsp,由这个控制器向不同的JSP页面转发请求。图1-9显示了其体系结构。
图1-9使用了一个名为action的请求属性来确定要把请求转发到哪里。第一次访问index.jsp 时,action属性没有值。在这种情况下,请求会转发到prodform.jsp页面。prodform.jsp页面提示输入商品信息,其中还包含内置的客户端验证。从prodform.jsp提交数据时,action属性就有了值prodsubmit。如果action属性的值为prodsubmit,index.jsp 会把请求转发给procprod.jsp。procprod.jsp 页面再显示为商品输入的值。

图1-9 利用了前端控制器的应用流程
(1)使用前端控制器转发请求
本例中的前端控制器是index.jsp页面,位于
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
这里使用了一个JSTL
如果action属性的值为prodsubmit,请求就会转发到procprod.jsp 页面进行处理:







