Chap. 2 Servlet接口
Servlet接口是Java Servlet API的重要抽象。所有的servlet直接实现这个接口,或者更常见的是扩展实现这个接口的一个类。在Java Servlet API中有两个类实现了Servlet接口,它们是GenericServlet和HttpServlet。在大多数情况下,开发者将扩展HttpServlet来实现它们的servlet。
2.1 请求处理方法
基本的Servlet接口定义了一个处理客户端请求的service方法。当servlet容器将每个请求路由到servlet实例时,会调用这个方法。
处理Web应用程序的并发请求,通常需要Web开发者设计的servlet,能够在特定时间,在service方法内处理多线程的执行。一般来说,Web容器处理到同一个servlet的并发请求是通过在不同线程中并发执行service方法来实现的。
2.1.1 HTTP特定的请求处理方法
HttpServlet抽象子类在基本的Servlet接口中增加了额外的方法,这些方法可以被service方法自动调用帮助处理基于HTTP的请求。这些方法是:
•doGet 处理HTTP GET请求
•doPost 处理HTTP POST请求
•doPut 处理HTTP PUT请求
•doDelete 处理HTTP DELETE请求
•doHead 处理HTTP HEAD请求
•doOptions 处理HTTP OPTIONS请求
•doTrace 处理HTTP TRACE请求
通常在开发基于HTTP的servlet时,Servlet开发者只需要关心自己的doGet和doPost方法。其他方法被认为是非常熟悉HTTP编程的程序员使用的方法。
2.1.2 额外的方法
doPut和doDelete方法允许Servlet开发者支持使用HTTP/1.1特性的客户端。HttpServlet中的doHead方法是一种特殊形式的doGet方法,只返回由doGet方法产生的头信息。doOptions方法响应由servlet支持的HTTP方法。doTrace方法生成的响应,包含TRACE请求中发送的所有头信息的实例。
2.1.3 有条件的GET支持
HttpServlet接口中定义了getLastModified方法,支持有条件的GET操作。有条件的GET操作请求的资源只有在指定时间内被修改了才需要发送
。在适当的情形,实现该方法可以帮助有效地利用网络资源。
2.2 实例的数量
Web应用程序部署描述符中的servlet声明包含servlet,在第十三章“部署描述符”中介绍,它控制servlet容器如何提供servlet实例。
因为servlet不运行于分布式环境(默认),servlet容器必须为每个servlet声明使用一个实例。然而,对于实现了SingleThreadModel接口的servlet,servlet容器可能实例化多个实例来处理沉重的的请求负载和序列化请求到特定的实例。
在作为应用程序一部分部署的servlet在部署描述符中标记为distributable的情况下,容器可能在每个Java虚拟机(JVM)的每个servlet声明中只有一个实例。但是,如果在分布式应用中的servlet实现了SingleThreadModel接口,容器可能在容器的每个JVM中实例化多个servlet实例。
2.2.1 单线程模式的注释
SingleThreadModel接口的使用保证了同一时间只有一个线程执行给定的servlet实例的service方法。重要的是注意这个保证只适用于每个servlet实例,因为容器可以选择池化那些对象。对象可以在同一时间被多个servlet实例访问,例如HttpSession实例,在任何特定时间对于多个servlet都是可用的,包括那些实现singleThreadModel的servlet。
建议开发者使用其他方法解决这些问题而不是去实现这个接口,例如避免使用实例变量或者同步访问资源的代码块。SingleThreadModel接口在这个版本的规范中是不被推荐使用的。
2.3 Servlet生命周期
Servlet通过明确的生命周期定义来管理,这个生命周期定义了servlet如何加载并实例化、初始化,处理客户端请求,以及从服务中除去。生命周期体现为API中javax.servlet.Servlet接口的init,service,和destroy方法,所有的servlet必须直接或间接的通过GenericServlet或HttpServlet抽象类来实现。
2.3.1 加载和实例化
Servlet容器负责加载和实例化servlet。加载和初始化可以发生在容器启动时,或者延迟直到容器决定servlet需要服务请求的时候。
当servlet引擎启动时,servlet容器必须加载需要的servlet类。Servlet容器使用普通的Java类加载机制加载servlet类。加载可以从本地文件系统,远程文件系统,或者其他的网络服务。
在加载Servlet类之后,容器会实例化它来使用。
2.3.2 初始化
在servlet对象被实例化之后,容器必须在它处理客户端请求之前初始化它。初始化提供以便servlet可以读取持久化的配置数据,初始化昂贵的资源(例如基于JDBC API的连接),和执行其他一次性的活动。容器通过调用唯一的(每个servlet声明)实现了ServletConfig接口的对象为参数的Servlet接口的init方法初始化servlet实例。配置对象允许servlet访问Web应用程序配置信息中的name-value初始化参数。配置对象也提供给servlet可以访问的描述servlet运行时环境信息的对象(实现了ServletContext接口)。更多关于ServletContext接口的信息参见第三章“servlet上下文”。
2.3.2.1 初始化中的错误条件
初始化过程中,servlet实例可以抛出UnavailableException或ServletException。在这种情况下,servlet一定不会被置为有效的服务,并且一定会被容器释放掉。destroy方法没有被调用,因为它被认为是不成功初始化。
在初始化失败后,容器可以实例化和初始化一个新的实例。这种规则的例外是,当用UnavailableException表示最小不可用时间,容器必须在创建和初始化新的servlet实例之前等待这段时间。
2.3.2.2 工具考虑
当工具加载和内省Web应用程序的时候,静态初始化方法的触发和调用init方法是不同的。开发者不能假定servlet处于活动容器运行状态,直到Servlet接口的init方法被调用。例如,servlet不应试图在静态(类)初始化方法被调用时,建立数据库或Enterprise JavaBeans容器的连接。
2.3.3 请求处理
在servlet被正确地初始化之后,servlet容器可以用它来处理客户端请求。请求由ServletRequest类型的request对象表示。Servlet通过调用ServletResponse对象提供的方法填充该请求的响应。这些对象作为参数传递给Servlet接口的service方法。
在HTTP请求的情况下,容器提供HttpServletRequest和HttpServletResponse类型的对象。
注意,servlet容器放置到服务中的servlet实例,可以在生命周期中不处理任何请求。
2.3.3.1 多线程问题
Servlet容器可以通过servlet的service方法发送并发请求。为了处理这些请求,servlet开发者必须为service方法中的多线程并发处理做好足够的准备。
虽然不建议,开发者的一种选择是实现SingleThreadModel接口,这样容器保证在service方法中在同一时间只有一个请求线程。Servlet容器可以通过序列化servlet上的请求来满足这个需求,或者维护一个servlet实例池。如果servlet是Web应用程序的一部分,并且已经被标记为分布式,那么容器可以在每个应用程序分布式访问的JVM中维护servlet实例池。
对于没有实现SingleThreadModel接口的servlet,如果service方法(或者由HttpServlet抽象类的service方法转发的doGet或doPost这类方法)已经使用synchronized关键字进行定义,servlet容器不能使用实例池方法,但是必须序列化传入的请求。在这种情况下,强烈建议开发者不要同步service方法(或者这个方法转发的方法),因为对性能产生不利的影响。
2.3.3.2 请求处理期间的异常
Servlet在服务请求期间可能抛出ServletException或者UnavailableException。ServletException表示在处理请求期间发生了一些错误,容器应该采取适当的措施来清理请求。
UnavailableException表示servlet不能处理请求,暂时性的或者永久性的。
如果UnavailableException表示的是永久性的不可用,那么servlet容器必须从服务中移除servlet,调用destroy方法,并释放servlet实例。由于这个原因容器拒绝任何请求,必须返回SC_NOT_FOUND (404)响应。
如果UnavailableException表示的是暂时性的不可用,容器可以选择在这个暂时不可用期间内不向它路由任何请求。在此期间任何被容器拒绝的请求,必须返回SC_SERVICE_UNAVAILABLE (503)响应以及Retry-After头信息,指明不可用将何时终止。
容器可以选择忽略永久性和暂时性不可用的区别,把所有的UnavailableException看作永久性的,因此从服务中移除抛出UnavailableException的servlet。
2.3.3.3 线程安全
请求和响应对象的实现不保证线程安全。这意味着它们只应该在请求处理线程的作用域内被使用。
请求和响应对象的引用不应该交给在其他线程里运行的对象,这样会导致行为的不确定性。如果应用程序创建的线程使用了容器管理的对象,例如请求或者响应对象,这些对象必须只在servlet的service生命周期中访问,并且这些线程的生命周期必须处于servlet的service方法的生命周期之内,因为在service方法结束后,再访问这些对象,可能导致不确定的问题。注意请求和响应对象不是线程安全的。如果在多线程中访问这些对象,访问必须同步,或者通过包装来添加线程安全,例如,同步调用访问请求属性的方法,或者在线程内给响应对象使用一个本地的输出流。
2.3.4 结束服务
Servlet容器不需要在任何特定的时间内保持servlet被装载。Servlet实例可以在servlet容器中的一段毫秒内保持活动,或者和servlet容器的寿命一样(可以是几天,几个月或几年),或者任何之间的时间。
当servlet容器确定要将servlet从服务中移除时,会调用Servlet接口的destroy方法,使servlet释放任何它使用的资源,以及保存任何持久化的状态。例如,容器可以在需要节约内存资源时这样做,或者当它被关闭时。
在servlet容器调用destroy方法之前,它必须允许任何当前正在运行servlet的service方法的线程完成执行,或者超过服务器定义的时间限制。
一旦servlet实例的destroy方法被调用,容器就不会把其它请求路由给那个servlet实例。如果容器需要再次启用servlet,它必须重新new一个此servlet类的实例。
在destroy方法执行完毕后,container必须释放这个servlet实例,以便它可以被垃圾回收。
分享到:
相关推荐
Servlet-2.4 规范是 Java Servlet API 的一个重要版本,发布于2003年4月10日,由 Sun Microsystems 提出并维护。此版本在先前版本的基础上进行了改进与扩展,提高了应用的安全性、灵活性和功能丰富度。 #### 二、...
Servlet 2.4 规范是Java Web开发中一个重要的里程碑,它定义了Servlet和Java服务器页面(JSP)的标准,使得开发人员可以构建可移植的、基于Web的应用程序。以下是对Servlet 2.4规范的详细解读: 1. **概述** - **...
Java Servlet Specification 2.4(简称 JSS 2.4)是 Sun Microsystems 发布的一个规范文档,用于定义 Servlet 技术的标准实现。该版本发布于 2003 年 4 月 10 日,作为 Proposed Final Draft 3 版本。Servlet 是一种...
这两个版本的Servlet规范文档是开发者深入理解Servlet技术、提高Web应用开发效率的重要参考资料。通过学习这些规范,开发者能够充分利用Servlet提供的功能,构建出高效、健壮的Web应用程序。无论是Servlet 2.4的过滤...
1.6 与 Java Servlet 规范 2.5 版本间的兼容性 ..............................................................................................14 1.6.1 监听器(Listener)顺序 .................................
Servlet 2.4 规范是Java服务器端编程的一个重要里程碑,它定义了Servlet和JavaServer Pages (JSP) 的核心API,为开发基于Java的Web应用程序提供了标准。这一规范在Java EE 5之前广泛使用,是理解Web服务构建基础的...
Servlet 2.4 规范是Java服务器端编程的重要组成部分,它是Java EE 5标准的一部分。这个规范定义了Servlet API的版本2.4,为Web应用程序提供了处理HTTP请求和响应的能力。Servlet技术允许开发人员创建动态、交互式的...
Servlet 2.4 API 是Java Web开发中一个重要的组件,它是Java Servlet技术的规范版本2.4。这个压缩包文件 "servlet2.4_API.rar" 包含了一系列的文档和资源,帮助开发者理解和使用Servlet API。以下是这些文件的具体...
Servlet API 2.4是Java Servlet规范的第2个主要版本,发布于2003年,它是Java 2平台企业版(J2EE)1.4的一部分。 Servlet是Java编程语言中用于动态处理Web请求的类库,它们允许开发者创建能够接收和响应HTTP请求的...
2.5版本:此版本对servlet规范进行了更进一步的改进,特别是在2.4版本的基础上解决了多个URL不能映射到同一个servlet的问题。此外,servlet 2.5版本还提供了更多的编程便利性,例如,与Servlet API的更好集成、更...
Servlet 2.4 版本是 Java Servlet 规范的一个重要里程碑,它在 2002 年由 Sun Microsystems 发布。 #### Servlet 2.4 规范关键特性 ##### 1. **过滤器(Filter)机制** Servlet 2.4 引入了过滤器机制,允许开发者在...
Servlet 2.4 API是Java Servlet规范的第三个版本,发布于2003年,它在Servlet 2.3的基础上增加了新的特性和改进。 二、Servlet生命周期 Servlet的生命周期包括加载、初始化、服务、销毁四个阶段。在Servlet 2.4中,...
Servlet 2.4是Servlet规范的第四次重大更新,它是Java Servlet API的重要组成部分,主要用于处理HTTP请求和响应。在这个版本中,有以下几个关键知识点: 1. **Servlet生命周期**:Servlet实例经历了初始化、服务和...
Servlet 2.4 标准是 Java Servlet API 的一个重要版本,它定义了 Web 应用程序如何处理 HTTP 请求和响应的基本规范。该标准由 Sun Microsystems 在 2003 年 11 月 24 日发布,其版本号为 2.4。本文档提供了 Servlet ...
它遵循特定的技术规范,随着技术的发展,Servlet规范也经历了多次迭代。 - **JSR53**: 定义了Java TM Servlet 2.3 和 Java Server Pages TM 1.2 规范。 - **JSR154**: 分别定义了Java TM Servlet 2.4 和 2.5 (维护...
Servlet 2.4是Java Servlet规范的一个版本,它在2003年由Java Community Process (JCP)发布,是Java Web开发中的重要组成部分。这个压缩包文件“servlet2.4doc”很可能包含了该版本Servlet API的官方文档,用于帮助...
- 发布于1999年,是Servlet规范的第二个主要版本。 - 引入了HttpServletRequest和HttpServletResponse接口,以支持HTTP协议的特性,如请求头和响应状态码。 - 提供了RequestDispatcher接口,用于请求转发和包含,...
Servlet 2.4是Java Servlet规范的一个版本,它在2003年发布,是Java Web开发中的一个重要里程碑。Servlet是Java平台上的一个标准接口,用于处理来自HTTP客户端(通常是Web浏览器)的请求并返回响应。它使得开发者...
Servlet 2.4是Java Servlet规范的一个版本,它在2003年由Java Community Process (JCP)发布,是Java Web开发的重要组成部分。这个版本的Servlet API为Web开发者提供了更强大的功能和更好的性能,同时也引入了一些...
Neusoft公司Java编码规范 目的 5 范围 6 前提条件 7 Java编码规范概要 8 1 代码风格 8 1.1 一般格式说明 8 1.2 基本结构 8 2 代码结构 9 2.1 变更履历 9 2.2 Package声明 11 ...5.12 Servlet规范 63 5.13 EJB规范 65