Web应用程序的历史

1.1 Web应用程序的历史

虽然servlet可以用来扩展任何启用Java的服务器的功能,但它们最常用于扩展Web服务器,从而为CGI脚本提供了强大、高效的替换。当您使用servlet为网页创建动态内容或以其他方式扩展web服务器的功能时,实际上是在创建web应用程序。虽然网页仅显示静态内容并允许用户浏览该内容,但web应用程序提供更多交互式体验。Web应用程序可以像文档存档中的关键字搜索一样简单,也可以像电子店面一样复杂。Web应用程序正在Internet上以及企业内部网和外联网上部署,在那里,它们具有提高生产力和改变大公司和小公司做生意的方式的潜力。

为了理解servlet的强大功能,我们需要回过头来看看可用于创建Web应用程序的其他一些方法。

1.1.1公共网关接口CGI

公共网关接口(通常称为CGI)是创建动态内容的第一批实用技术之一。使用CGI,Web服务器将某些请求传递给外部程序。然后将该程序的输出发送到客户端,代替静态文件。CGI的出现使得在网页中实现各种新功能成为可能,并且CGI很快成为事实上的标准,在许多Web服务器上实现。

值得注意的是,CGI程序创建动态网页的能力是其预期目的的副作用:为信息服务器定义与外部应用程序通信的标准方法。这个起源解释了为什么CGI可能是可想象的最坏的生命周期。当服务器接收到访问CGI程序的请求时,它必须创建一个新进程来运行CGI程序,然后通过环境变量和标准输入将生成响应可能需要的所有信息传递给它。为每个这样的请求创建一个流程需要时间和大量的服务器资源,这限制了服务器可以同时处理的请求数量。图1-1显示了CGI生命周期。

我们可以看到CGI为每一个请求都创建一个进程来处理。就算访问的地址是一样的。

即使CGI程序可以用几乎任何语言编写,Perl编程语言也已经成为主要的选择。Perl的高级文本处理能力在管理CGI接口的细节方面有很大帮助。用Perl编写CGI脚本使它看起来像平台独立性,但是它也要求每个请求启动一个单独的Perl解释器,这需要更多的时间和额外的资源。

CGI的另一个经常被忽视的问题是,CGI程序在开始执行时不能与Web服务器交互或利用服务器的能力,因为它是在单独的进程中运行的。例如,CGI脚本不能写入服务器的日志文件。

1.1.1.1 FASCGI

一个名为开放市场的公司开发了一个名为FastCGI的标准CGI的替代方案。在很多方面,FastCGI就像CGI一样工作——重要的区别在于FastCGI为每个FastCGI程序创建单个持久进程,如图1-2所示。这消除了为每个请求创建新进程的需要。

我们可以看到FASCGI 则每一个CGI创建一个进程。并且这个进程是持久的。

虽然FastCGI是朝着正确方向迈出的一步,但是它仍然存在线程扩散的问题:每个FastCGI程序至少有一个流程。如果一个FASCGI程序要处理并发请求,它需要一个进程池,每个请求一个进程池。考虑到每个进程都可能执行Perl解释器,这种方法不会像您希望的那样扩展。(尽管值得称赞的是,FastCGI可以将其进程分布在多个服务器上。)FastCGI的另一个问题是它不能帮助FastCGI程序与服务器更紧密地交互。最后,FASCGI程序只是作为它们编写的语言的可移植性。

1.1.1.2 PelLeX

由ActiveState开发的PerlEx提高了在WindowsNTWeb服务器(微软的Internet信息服务器和iPlanet的快速跟踪服务器和企业服务器)上用Perl编写的CGI脚本的性能。它有与FastCGI相似的优点和缺点。

1.1.2其他解决方案

CGI/Perl具有与平台无关的方式来产生动态Web内容的优点。其他用于创建Web应用程序的著名技术,如ASP和服务器端JavaScript,是仅用于特定Web服务器的专有解决方案。

1.1.2.4 JavaServer页面

JavaServer页面,通常称为JSP,是基于Java的替代ASP,由Sun发明和标准化。JSP使用类似ASP的语法,除了脚本语言是Java。与ASP不同,JSP是一个开放的标准,由几十个供应商在所有平台上实现。JSP与servlet紧密相连,因为JSP页面作为其执行的一部分被转换成servlet。在这本书中更详细地讨论了JSP。

1.1.3 Java Servlet

输入Java servlet。正如前面所说的,servlet是一个通用服务器扩展程序,可以动态加载Java类来扩展服务器的功能。servlet通常与Web服务器一起使用,它们可以取代CGI脚本。servlet与专用服务器扩展类似,除了它在服务器上运行Java虚拟机(JVM)外(参见图1-4),所以它是安全和可移植的。Servlet完全在服务器域内操作:不像applet,它们不需要在Web浏览器中支持Java。

Servlet运行在java虚拟机中的。每一个请求都是一个线程。并且相同的Servlet地址执行不同的Servlet。

与CGI和FastCGI(它们必须使用多个进程来处理单独的程序和/或单独的请求)不同,servlet可以由同一进程中的独立线程处理也可以由分布在多个后端服务器上的多个进程中的线程处理。这意味着servlet也是高效和可扩展的。因为servlet与Web服务器双向通信,所以它们可以与服务器非常紧密地交互,以完成CGI脚本所不能做的事情。

Servlet的另一个优点是它们是可移植的:既跨操作系统,又用于Java,也跨Web服务器。正如您将很快看到的,所有主要的Web服务器和应用服务器都支持servlet。我们相信JavaServlet为Web应用程序开发提供了最好的平台,在本章的后面,我们将对此有更多的发言权。

2.1 HTTP基础

在我们甚至能够向您展示一个简单的HTTP servlet之前,我们需要确保您对Web背后的协议HTTP的工作方式有基本的了解。如果您是一位经验丰富的CGI程序员(或者如果您已经完成了任何严肃的服务器端Web编程),那么可以安全地跳过这个部分。更好的是,您可以略过它来刷新关于GET和POST方法的更精细点的记忆。但是,如果您对服务器端Web编程领域还很陌生,那么您应该仔细阅读此材料,因为本书的其余部分将假定您理解HTTP。

2.1.1请求、响应和标题

HTTP是一种简单的无状态协议。客户端,例如Web浏览器,提出请求,Web服务器响应,事务完成。当客户端发送请求时,它指定的第一件事是HTTP命令,称为方法,它告诉服务器它希望执行的操作的类型。请求的第一行还指定文档(URL)的地址和它正在使用的HTTP协议的版本。例如:

GET /intro.html HTTP/1.0

此请求使用GET方法使用HTTP版本1请求名为intro.HTML的文档。在发送请求之后,客户端可以发送可选的报头信息,以告诉服务器关于请求的额外信息,例如客户端正在运行什么软件以及它理解什么内容类型。此信息不直接与所请求的内容有关,但它可以由服务器在生成响应时使用。以下是一些示例请求标题:

User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)

Accept: image/gif, image/jpeg, text/*, */*

User-Agent头提供有关客户端软件的信息,而Accept头指定客户端希望接受的媒体(MIME)类型。(我们将在第4章中讨论servlet上下文中的请求标头。)在标头之后,客户机发送空行,以指示标头部分的结束。客户机还可以发送附加数据(如果适合使用的方法),就像我们稍后将讨论的POST方法一样。如果请求不发送任何数据,它将以空行结束。

客户端发送请求后,服务器处理该请求并发送响应。响应的第一行是状态行,指定服务器正在使用的HTTP协议的版本、状态代码和状态代码的描述。例如:

HTTP/1.0 200 OK

此状态行包含200的状态代码,指示请求成功,因此描述OK。另一个常见的状态代码是404,其描述Not Found——正如您所猜到的,这意味着没有找到所请求的文档。第5章讨论了常见的状态代码以及如何在servlet中使用它们,而附录D提供了完整的HTTP状态代码列表。

在状态行之后,服务器发送响应头,告诉客户机服务器正在运行的软件和服务器响应的内容类型。例如:

Date: Saturday, 23-May-00 03:25:12 GMT

Server: Tomcat Web Server/3.2

MIME-version: 1.0

Content-type: text/html

Content-length: 1029

Last-modified: Thursday, 7-May-00 12:15:35 GMT

2.1.2 GET和POST

当客户端连接到服务器并发出HTTP请求时,请求可以是几种不同的类型,称为methods 。最常用的方法是GET和POST。简言之,GET方法被设计用于获取信息(文档、图表或数据库查询的结果),而POST方法被设计用于发布信息(信用卡号、一些新的图表数据或将要存储在数据库中的信息)。要使用公告板类比,GET是用于阅读和POST是用于提交新材料。

GET是直接在浏览器中键入URL或单击超链接时使用的方法;

在提交HTML表单时可以使用GET或POST。

尽管GET方法是为读取信息而设计的,但是作为请求的一部分,它还可以包括一些自己的信息,这些信息更好地描述了应该获取什么,比如动态创建的图表的x、y标度。此信息作为一个字符序列传递到请求URL中,称为查询字符串。以这种方式将额外信息放在URL中,可以使页面像其他任何东西一样被书签或电子邮件发送。因为GET请求理论上不需要发送大量的信息,所以一些服务器将URL和查询字符串的长度限制为约240个字符。

GET也可以发送一些信息给服务器的。我们可以配置一些参数和他的值。这样服务器就可以获取这些参数。比如百度搜索的时候的词语。

POST方法使用不同的技术向服务器发送信息,因为在某些情况下,它可能需要发送兆字节的信息。POST请求将其无限长度的所有数据直接传递到套接字连接,作为HTTP请求主体的一部分。客户端的交换是不可见的。URL根本不会改变。因此,POST请求不能被书签或电子邮件,或在某些情况下,甚至重新加载。这是由设计信息发送到服务器,如您的信用卡号码,应该只发送一次。POST在发送敏感信息时还提供了一点额外的安全性,因为记录所有URL访问的服务器的访问日志不会记录提交的POST数据。

在实践中,GET和POST的使用偏离了最初的意图。对于长参数化的信息请求来说,使用POST而不是GET来解决具有过长URL的问题是很常见的。对于使用GET上传信息的简单形式来说也是常见的,因为为什么不呢?一般来说,这不是一个很大的问题。请记住,GET请求(因为它们可以很容易地被书签)不应该被允许在服务器上造成更改,客户机可以对此负责。换句话说,GET请求不应该用于下订单、更新数据库或以任何方式采取显式客户端操作。

2.1.3其他方法

除了get和POST之外,还有几种其他使用较少的HTTP方法。有头的方法,这是送客户的时候就想只看到响应的标题,确定文件的大小、修改时间,或一般的可用性。还有,把文件直接放在服务器上,并删除,做相反的事情。由于复杂的政策问题,这两种情况并未得到广泛支持。跟踪方法被用作调试帮助,它返回给客户端其请求的确切内容。最后,选择方法可用于请求服务器,它支持什么方法或可供选择的服务器上的一个特定的资源。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注