我们用一个竞拍例子来讲述数据验证。这个例子将为用户提供一个表单,可以在其中输入商品竞拍信息。竞拍页面要对收到的竞拍价格进行检查,保证它处于0到999的合法范围内(包含0和999)。这个检查是用JSP编写的。下面突出显示的JSP代码完成了数据验证[1],采用的是传统的服务器端验证方式:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
scope="request">
value="Sorry, your bid is not in range. Please enter again."/>
这个验证使用JSTL
${(param.price <= 0) || (param.price >= 999)}
如果用户输入的竞拍价格超出了这个范围,则需要重新输入。表单输入由enterbid.jsp 页面处理。
尽管这个解决方案不错,但它并非完成数据验证的最佳方法。因为它的效率不高,所以建议不用,你会在下一节了解到这一点。
1.1.1 服务器端验证和资源的高效使用
为什么使用JSP完成数据验证的效率不高?图1-1展示了其中的原因。

图1-1 基于JSP的服务器端数据验证
在图1-1中,用户输入的数据得到验证之前,必须在其浏览器和服务器之间进行传输。如果数据有错误,就必须重新输入,并重新传输到服务器进行验证。由于JSP逻辑要在服务器端的容器中执行,所以用JSP实现的数据验证总是在服务器端发生。
使用JSP逻辑实现的数据验证在服务器端发生。
服务器端验证一般效率都很低,主要有以下几个原因:
q 每个验证和重试事件序列都要求进行一次网络调用。
q 验证任务会加重服务器在带宽和处理能力方面的负担。
q 在数据得到验证之前,用户可能必须等待相当长的时间;特别是其他用户向服务器发出了大量验证请求,服务器因此拥塞时,用户等待的时间更长。
现代客户计算机已经有很强的计算能力。目前流行的浏览器版本(如Microsoft Internet Explorer 6.x 和 Netscape 7.x)都提供了丰富的特性,并支持使用功能强大的脚本语言来编写客户端程序。因此可以充分地结合计算机的计算能力和浏览器的脚本功能,在客户端完成数据验证。图1-2示出了客户端验证。

图1-2 客户端数据验证的操作
在图1-2中,数据输入在客户端由浏览器上执行的脚本代码进行验证。如果检测到一个验证错误,用户会立即得到提示,要求修正输入。在整个过程中,没有任何网络访问。数据在客户端得到成功验证后,才会在客户端和服务器之间传输。
1.1.2 客户端数据验证
在客户端完成数据验证有以下好处:
q 服务器不再完成低级数据验证,因此得以减负。
q 由于不可能向服务器传送非法输入,所以可以节省带宽。
q 用户总是会很快得到响应,因为验证代码在功能强大的客户端硬件上执行。
由于客户端验证总是比服务器端验证更为高效,所以有人可能会认为所有数据验证都应该在客户端上完成。但是,在实际中这是不可能的,下一节将说明其中原委。
与服务器端验证相比,客户端数据验证往往能够更高效地使用资源。
1.1.3 服务器端验证的必要性
在客户端完成所有数据验证是不可能的,因为有些验证工作需要访问服务器资源。例如,一个应用在下订单之前可能需要确认某个商品有货,而这仅凭客户浏览器是无法确定的。
此外还有一个原因:某些用户使用的浏览器可能不支持脚本代码的执行。这种情况下,客户端数据验证就不可能实现。
并非所有验证任务都能在客户端完成。
1.1.4 常见的客户端数据验证
某些类型的数据验证任务可以而且也应该在客户端上完成。包括:
q 验证数字值确实是合法的数字。
q 验证文本输入数据的长度。
q 验证输入数据满足某种文本格式(例如全数字序列号、电话号码、信用卡号、电子邮件地址或邮政编码)。
q 检查数值数据的值域(如果值域固定,而且不依赖于服务器信息)。
以上所列的各个任务有一个共同的特点,这就是它们都能独立地完成,而不需要访问服务器端数据或信息。
因此,在一般的Web应用中,数据验证可以分为两个阶段。首先,客户端验证检查输入是否处于允许的范围内,并检查数据格式和类型的合法性。然后,服务器端验证(如果有)完成另外一些需要访问服务器端资源(如数据库)的检查。
在大多数实际应用中,在客户端和服务器上都会进行数据验证。







