Servlet定义的概述

Servlet是使用Java Servlet应用程序设计接口及相关类和方法的Java程序。它在Web服务器上或应用服务器上运行并扩展了该服务器的能力。Java Servlet对于Web服务器就好像Java Applet对于Web浏览器。Applet装入Web浏览器并在Web浏览器内执行,而Servlet则是装入Web服务器并在Web服务器内执行。 Java Servlet API 定义了Servlet和服务器之间的一个标准接口,这使得Servlet具有跨服务器平台的特性。

Servlet通过创建一个框架扩展服务器的能力,采用请求-响应模式提供Web服务。当客户机发送请求至服务器时,服务器将请求信息发送给Servlet,Servlet生成响应内容并将其传给Server,然后再由Server将响应返回给客户端。

Servlet的功能

Servlet的功能涉及范围很广。例如,Servlet可完成如下功能:

创建并返回一个包含基于客户请求性质的动态内容的完整的 HTML页面。

创建可嵌入到现有 HTML 页面中的一部分 HTML 页面(HTML 片段)。与其他服务器资源(文件、数据库、Applet、Java应用程序等)进行通信。

用多个客户机处理连接,接受多个客户机的输入,并将结果广播到多个客户机上。例如,Servlet 可以是多参与者的游戏服务器。

允许在单连接方式下传送数据的情况下,在浏览器上打开服务器至Applet的新连接,并将该连接保持在打开状态。允许客户机和服务器简单、高效地执行会话的情况下,Applet也可以启动客户浏览器和服务器之间的连接。可以通过定制协议或标准(如 IIOP)进行通信。

对特殊的处理采用 MIME 类型过滤数据,例如图像转换和服务器端(包括SSI)。

将定制的处理提供给所有服务器的标准例行程序。例如,Servlet 可以修改如何认证用户。

Java Servlet与现有网络技术的差别

那么Java Servlet与一些现有的网络技术有什么具体的差别呢?

Java Servlet与Applet之间的差别 从基本上来说,Servlet与 Applet 是截然相反的。Servlet可以被视为服务器方面的 Applet。Servlet在网络服务器内运行而Applet在网络浏览器内运行。浏览器提交一个请求执行Servlet的命令;而由于浏览器可直接命令Applet,所以它可以在运行时单机运行。

Java Servlet与CGI之间的差别 与传统的CGI和许多其他类似CGI的技术相比,Java Servlet具有更高的效率,更容易使用,功能更强大,具有更好的可移植性,更节省投资。其中最大的区别是在性能方面。

在传统的CGI中,每个请求都要启动一个新的进程,如果CGI程序本身的执行时间较短,启动进程所需要的开销很可能反而超过实际执行时间。而使用 Servlet时,服务器上仅有一个Java虚拟机在运行,只有当Servlet被调用时,它才被加载,且直到Servlet更改时,它才会被再次加载。在传统CGI中,如果有N个并发的对同一CGI程序的请求,则该CGI程序的代码在内存中重复装载了N次;而对于Servlet,处理请求的是N个线程,只需要一份Servlet类代码。在性能优化方面,Servlet也比CGI有着更多的选择,比如缓冲以前的计算结果,保持数据库连接的活动,等等。

通过使用Servlet API,开发人员不必担心服务器的内部运作方式。表格资料、服务器头、cookies等皆可通过Servlet处理。另外,因为Servlet是用 Java写的,能将其从一个服务器移到另一个服务器以供发布,同时不必担心操作系统或服务器的类型。这一优点充分体现了Java"一次编写,随处运行"的优越特性。

Servlet定义的生命周期

Servlet定义的生命周期讲述了一个Servlet如何被加载、初始化,以及它怎样接收请求、响应请求、提供服务。

在代码中,Servlet生命周期由接口javax.servlet.Servlet定义。所有的Java Servlet 必须直接或间接地实现javax.servlet.Servlet接口,这样才能在Servlet Engine上运行。

Servlet Engine提供network Service,响应MIME request,运行Servlet Container。 javax.servlet.Servlet接口定义了一些方法,在Servlet 的生命周期中,这些方法会在特定时间按照一定的顺序被调用。

Servlet定义之如何被加载(Load)、被实例化(Instantiated)

Servlet Engine 负责实例化和加载Servlet,这个过程可以在Servlet Engine 加载时执行,可以在Servlet 响应请求时执行,也可以在两者之间的任何时候执行。

Servlet如何被初始化(Initialized)

Servlet Engine 加载好Servlet 后,必须要初始化它。初始化时Servlet 可以从数据库里读取初始数据,建立JDBC Connection,或者建立对其他有价值的资源的引用。

在初始化阶段,Init( )方法被调用。这个方法在javax.servlet.Serlet接口中定义。Init( )方法以一个Servlet 配置文件(ServletConfig 型)为参数。Servlet configuration 对象由Servlet Engine 实现,可以让Servlet 从中读取一些name-value对的参数值。ServletConfig对象还可以让Servlet接受一个Servlet Context对象。

Servlet 如何处理请求

Servlet 被初始化以后,就处于能响应请求的就绪状态。每个对Servlet 的请求由一个Servlet Request 对象代表。Servlet 给客户端的响应由一个Servlet Response对象代表。当客户端有一个请求时,Servlet Engine 将ServletRequest 和ServletResponse对象都转发给Servlet,这两个对象以参数的形式传给Service方法。这个方法由 javax.servlet.Servlet定义并由具体的Servlet 实现。

Servlet还可以实现 ServletRequest 和ServletResponse接口。ServletRequest接口可以让Servlet 获取客户端请求中的参数,如form data、request信息、协议类型,等等。Servlet 可以从ServletInputStream流中读取request 数据。ServletResponse接口允许Servlet设置response headers和status codes。实现这个接口可以使Servlet能访问ServletOutputStream流用来向客户端返回数据。

Servlet如何被释放

Servlet Engine 没有必要在Servlet定义的生命周期的每一段时间内都保持Servlet的状态。Servlet Engine可以随时随意使用或释放Servlet。因此,你不能依赖Servlet class或其成员存储信息。当Servlet Engine判断一个Servlet应当被释放时(比如说Engine准备Shut down 或需要回收资源),Engine必须让Servlet 能释放其正在使用的任何资源,并保存持续性的状态信息。这些可以通过调用Servlet的destroy方法实现。 在Servlet Engine 释放一个Servlet 以前,必须让其完成当前实例的service方法或是等到timeout(如果Engine定义了timeout)。当Engine释放一个 Servlet以后,Engine将不能再将请求转发给它,Engine必须彻底释放该Servlet并将其标明为可回收的(给garbage collection)。

在Servlet API中最重要的是Servlet interface。所有的Servlets执行这个interface的方式有很多种:或者是直接的,或者通过extending这个class执行它,如 HttpServlet。这个Servlet interface 提供并安排Servlet与客户端联系的方法。Servlet 编写者可以在他们开发Servlet程序时提供更多一些或所有这样的方法。

当一个Servlet接收来自客户端的调用请求时,它接收两个对象:一个是ServletRequest,另外一个是ServletResponse。这个ServletRequest class 概括从客户端到服务器之间的联系,而 ServletResponse class 概括从Servlet返回客户端的联系。

ServletRequest interface 可以获取到这样一些信息,如由客户端传送的参数名称,客户端正在使用的协议,产生请求并且接收请求的服务器远端主机名。它也提供获取数据流的 Servlet、ServletInputStream,这些数据是客户端引用中使用HTTP POST和PUT方法递交的。一个ServletRequest的子类可以让Servlet获取更多的协议特性数据。

例如,HttpServletRequest 包含获取HTTP-specific头部信息的方法。ServletResponse interface 给出相应客户端的Servlet方法。它允许Servlet设置内容长度和回应的MIME类型,并且提供输出流ServletOutputStream,通过编写者可以发回相应数据。ServletResponse子类可以给出更多protocol-specific容量的信息。例如,HttpServletResponse 包含允许Servlet操作HTTP-specific头部信息的方法。

相关推荐