1.1Servlet的功能
Servlets是运行在Web或应用服务器上的Java程序,它是一个中间层,负责连接来自Web浏览器或其他HTTP客户程序的请求和HTTP服务器上的数据库或应用程序。Servlet的工作是执行西门的任务,如图1.1所示 。
图1.1Web中间件的作用
(1) 读取客户发送的显式数据。
最终用户一般在页面的HTML表单中输入这些数据。然而,数据还有可能来自applet或定制的HTTP客户程序。
(2) 读取由浏览器发送的隐式请求数据。
图1.1中显示了一条从客户端到Web服务器的单箭头,但实际上从客户端传送到Web服务器的数据有两种,它们分别为用户在表单中输入的显式数据,以及后台的HTTP信息。两种数据都很重要。HTTP信息包括cookie、浏览器所能识别的媒体类型和压缩模式等。
图1.1
(3) 生成结果。
这个过程可能需要访问数据库、执行RMI或EJB调用、调用Web服务,或者直接计算得出对应的响应。实际的数据可能存储在关系型数据库中。该数据库可能不理解HTTP,或者不能返回HTML形式的结果,所有Web浏览器不能直接与数据库进行会话。即使它能够做到这一点,为了安全上的考虑,我们也不希望让它这么做。对应大多数其他应用
程序,也存在类似的问题。因此,我们需要Web中间层从HTTP流中提取输入数据,与应用程序会话,并将结果嵌入到文档中。
(4) 向客户发送显式数据(即文档)。
这个文档可以用各种格式发送,包括文本(HTML或XML),二进制(GIF图),甚至可以式建立在其他底层格式之上的压缩格式,如gzip。但是,到目前为止,HTML式最常用的格式,故而servlet和JSP的重要任务之一就式将结果包装到HTML中。
(5) 发送隐式的HTTP响应数据。
图1.1中显示了一条从Web中间层到客户端的单箭头。但是,实际发送的数据有两种:文档本身,以及后台的HTTP信息。同样,两种数据对开发来说都式至关重要的。HTTP响应数据的发送过程涉及告知浏览器或其他客户程序所返回文档的类型(如HTML),设置cookie和缓存参数,以及其他类似的任务。
1.2动态构建网页的原因
预先建立的文档可以满足客户的许多请求,服务器无需调用servlet就可以处理这些请求。然而,许多情况下静态的结果不能满足要求,我们需要针对每个请求生成一个页面。实时构建页面的理由有很多种:
1、网页基于客户发送的数据。
例如,搜索引擎生成的页面,以及在线商店的订单确认页面,都要针对特定的用户请求而产生。在没有读取到用户提交的数据之前,我们不知道应该显示什么。要记住,用户提交两种类型的数据:显示(即HTML表单的数据)和隐式(即HTTP请求的报头)。两种输入都可用来构建输出页面。基于cookie值针对具体用户构建页面的情况尤其普遍。
2、页面由频繁改变的数据导出。
如果页面需要根据每个具体的请求做出相应的改变,当然需要在请求发生时构建响应。但是,如果页面周期性地改变,我们可以用两种方式来处理它:周期性地在服务器上构建新的页面(和客户请求无关),或者仅仅在用户请求该页面时再构建。具体应该采用哪种方式要根据具体情况而定,但后一种方式常常更为方便,因为它只需简单地等待用户的请求。例如,天气预报或新闻网站可能会动态地构建页面,也有可能会返回之前构建的页面(如果它还是最新的话)。
3、页面中使用了来自公司数据库或其他数据库断数据源的信息。
如果数据存储在数据库中,那么,即使客户端使用动态Web内容,比如applet,我们依旧需要执行服务器端处理。想象以下,如果一个搜索引擎网站完全使用applet,那么用户将会看到:“正在下载50TB的applet,请等待!”。显然,这样很愚蠢;这种情况下,我们需要与数据库进行会话。从客户端到Web层再到数据库(三层结构),要比从applet直接到数据库(二层结构)更灵活,也更安全,而性能上的损失很少甚至没有。毕竟数据库调用通常是对速度影响最大的步骤,因而,经过中间层可以执行高速缓存和连接共享。
理论上讲,servlet并非只用于处理HTTP请求的Web服务器或应用服务器,它同样可以用于其他类型的服务器。例如,servlet能够嵌入到FTP或邮件服务器中,扩展他们的功能。而且,用于会话启动协议服务器的servlet API最近已经被标准化(参见http://jcp.org/en/jsr/detail?id=116)。但在实践中,servlet的这种用法尚不流行,在此,我们只论述HTTP Servlet。
1.3 Servlet相对于“传统”CGI的优点
和传统CGI及许多类CGI技术相比,Java servlet效率更高、更易用、更强大、更容易移植、更安全、也更廉价。
1、效率
应用传统的CGI,针对每个HTTP请求都用启动一个新的进程。如果CGI程序自身相对比较简短,那么启动进程的开销会占用大部分执行时间。而使用servlet,Java虚拟机会一直运行,并用轻量级的Java线程处理每个请求,而非重量级的操作系统进程。类似地,应用传统的CGI技术,如果存在对同一CGI程序的N个请求,那么CGI程序的代码会载入内存N次。同样的情况,如果使用servlet则启动N个线程,单仅仅载入servlet类的单一副本。这种方式减少了服务器的内存需求,通过实例化更少的对象从而节省了时间。最后,当CGI程序结束对请求的处理之后,程序结束。这种方式难以缓存计算结果,保持数据库连接打开,或是执行依靠持续性数据的其他优化。然而,servlet会一直停留在内存中(即使请求处理完毕),因而可以直接存储客户请求之间的任意复杂数据。
2、便利
Servlet提供大量的基础构造,可以自动分析和解码HTML的表单数据,读取和设置
HTTP报头,处理cookie,跟踪会话,以及其他次类高级功能。而在CGI中,大部分工作都需要我们资金完成。另外,如果您已经了解了Java编程语言,为什么还有学校Perl呢?您已经承认应用Java技术编写的代码要比Visual Basic,VBScript或C++编写的代码更可靠,且更易重用,为什么还有倒退回去选择那些语言来开发服务器端的程序呢?
3、强大
Servlet支持常规CGI难以实现或根本不能实现的几项功能。Servlet能够直接于Web服务器对话,而常规的CGI程序做不到这一点,至少在不使用服务器专有API的情况下是这样。例如,与Web服务器的通信使得讲相对URL转换成具体的路径名变得更为容易。多个servlet还可以共享数据,从而易于实现数据库连接共享和类似的资源共享优化。Servlet还能维护请求之间的信息,使得诸如会话跟踪和计算结果缓存等技术变得更为简单。
4、可移植性
Servlet使用Java编程语言,并且遵循标准的API。所有主要的Web服务器。实际上都直接或通过插件支持servlet。因此。为Macromedia JRun编写的servlet,可以不经过任何修改地在Apache Tomcat,Microsoft Internet Information Server,IBM WebSphere 。iPlanet Enterprise Server。Oracle9i AS 或者StrNine WebStar上运行。他们是java2平台企业版的一部分,所以对servlet的支持越来越普遍。
5、廉价
对于开发用的网站、低容量或中等容量网站的部署,有大量免费或极为廉价的Web服务器可供选择。因此,通过使用servlet和jsp,我们可以从免费或廉价的服务器开始,在项目获得初步成功后,在移植到更高性能或高级管理工具的昂贵的服务器上。这与其他CGI方案形成鲜明的对比,这些CGI方案在初期都需要为购买专利软件包投入大量的资金。
价格和可移植性在某种程度上是相互关联的。例如,Marty记录了所有通过电子邮件向他发送问题的读者的所在国。印度接近列表的顶端,可能仅次于美国。Marty曾在马尼拉讲授过jsp和servlet培训课程,那儿对servlet和jsp技术抱很大的兴趣。
那么,为什么印度和菲律宾都对这项技术着呢感兴趣呢?我们推测答案可能分两部分。首先,这两个国家都拥有大量训练有素的软件开发人员。其次,这两个国家的货币
对美元的汇率都极为不利。因此,从美国公司那里购买专用Web服务器会消耗掉项目的大部分前期资金。
但是,使用servlet 和JSP,他们能够从免费的服务器开始:Apache Tomcat。项目取得成功之后,他们可以转移到性能更高、管理更容易,但需要付费的服务器。他们的servlet和jsp不需要重写编写。如果他们的项目变得更庞大,他们或许希望转移到分布式环境。没有问题:他们可以转而使用Macromedia JRun Professional,该服务器支持分布式应用。同样,他们的servlet和jsp没有任何部分需要重写。如果项目变得极为庞大,错综复杂,他们或许希望使用Enterprise JavaBeans来封装他们的商业逻辑。因此,他们可以切换到BEA WebLogic或Oracle9i AS。同样,不需要对servlet和jsp做出更改。最后,如果他们的项目变得更庞大,他们或许将他从Linux转移到运行IBM WebSphere的IBM大型机上。他们还是不需要做出任何更改。
6、安全
传统CGI程序中主要的漏洞来源之一就是,CGI程序常常由通过的操作系统外壳来执行。因此,CGI程序必须仔细地过滤掉那些可能被外壳特殊处理的字符,如反引导和分号。实现这项预防措施的难度可能超出我们的想象,在广泛应用的CGI库中,不断发现由这类问题引发的弱点。
问题的第二个来源是,一些CGI程序用不自动检查数组和字符串边界的语言编写而成。例如,在C和C++中,可以分配一个100个元素的数组,然后向第999个“元素“写入数据——实际上是程序内存的随机部分,这完全合法。因而,如果程序员忘记执行这项检查,就会将系统暴露在蓄意或偶然的缓冲区溢出攻击之下。
Servlet不存在这些问题。即使servlet执行系统调用激活本地操作系统上的程序,它也不会用到外壳来完成这项任务。当然,数组边界的检查以及其他内存包含特性是java编程语言的核心部分。
7、主流
虽然存在许多很好的技术,但是,如果提供商助支持他们,或开发人员不知道如何使用这些技术,那么它们的优点又如何体现呢?servlet和jsp技术得到服务器提供商的广泛支持,包括Apache,Oracle,IBM,Sybase,BEA,Maromedia,Causho,Sun/iPlanet,New Atlanta,ATG,Fujitsu,Lutris,Silverstream,World Wide Web Consortinrm ,以及其他服务器。存在几种低廉的插件,通过应用这些插件,Microsoft IIS和Zeus 5也同样支持servlet和jsp技术,它们运行在Windows,Unix/Linus,MacOS,VMS,和IBM大型机操作系统之上。它们用在航空业、电子商务、在线银行、web搜索引擎、门户、大型金融网站、以及成百上千您日常光顾的其他网站。
当然,仅仅是流行并不能证明技术的优越性。很多泛美的例子。但我们的立场是:服务器端Java本非一项新的、为经证实的技术。