servlet概述

本文摘自servlet3.1规范

1 什么是servlet?

Servlet 是基于 Java 技术的 web 组件,容器托管的,用于生成动态内容。像其他基于 Java 的组件技术一样,Servlet 也是基于平台无关的 Java 类格式,被编译为平台无关的字节码,可以被基于 Java 技术的 web server动态加载并运行。

容器,有时候也叫做 servlet 引擎,是 web server 为支持 servlet 功能扩展的部分。客户端通过 Servlet 容器实现的请求/应答模型与 Servlet 交互。

2 什么是servlet容器?

Servlet 容器是 web server application server 的一部分,提供基于请求/响应发送模型的网络服务,解码基于 MIME 的请求,并且格式化基于 MIME 的响应。 Servlet 容器也包含了管理 Servlet 生命周期。
Servlet 容器可以嵌入到宿主的 web server 中,或者通过 Web Server 的本地扩展 API 单独作为附加组件安装。Servelt 容器也可能内嵌或安装到包含 web 功能的 application server 中。
所有 Servlet 容器必须支持基于 HTTP 协议的请求/响应模型,比如像基于 HTTPSHTTP over SSL)协议的请求/应答模型可以选择性的支持。容器必须实现的 HTTP 协议版本包含 HTTP/1.0 HTTP/1.1。

因为容器或许支持 RFC2616 (HTTP/1.1)描述的缓存机制,缓存机制可能在将客户端请求交给 Servlet 处理之前修改它们,也可能在将 Servlet 生成的响应发送给客户端之前修改它们,或者可能根据 RFC2616 规范直接对请求作出响应而不交给 Servlet 进行处理。
Servlet 容器应该使 Servlet 执行在一个安全限制的环境中。在 Java 平台标准版(J2SE, v.1.3 或更高) 或者Java 平台企业版(Java EE, v.1.3 或更高) 的环境下,这些限制应该被放置在 Java 平台定义的安全许可架构中。

比如,高端的 application server 为了保证容器的其他组件不受到负面影响可能会限制 Thread 对象的创建。
Java SE 6 是构建 Servlet 容器最低的 Java 平台版本 。

3 一个典型的事件序列
1、客户端(如 web 浏览器)发送一个 HTTP 请求到 web 服务器;
2Web 服务器接收到请求并且交给 servlet 容器处理, servlet 容器可以运行在与宿主 web 服务器同一个进程中,也可以是同一主机的不同进程,或者位于不同的主机的 web 服务器中,对请求进行处理。
3servlet 容器根据 servlet 配置选择相应的 servlet,并使用代表请求和响应对象的参数进行调用。
4servlet 通过请求对象得到远程用户, HTTP POST 参数和其他有关数据可能作为请求的一部分随请求一起发送过来。 Servlet 执行我们编写的任意的逻辑,然后动态产生响应内容发送回客户端。发送数据到客户端是通过响应对象完成的。
5、一旦 servlet 完成请求的处理, servlet 容器必须确保响应正确的刷出,并且将控制权还给宿主 Web 服务器。
4 servlet接口

Servlet 接口是 Java Servlet API 的核心抽象。所有 Servlet 类必须直接或间接的实现该接口,或者更通常做法是通过继承一个实现了该接口的类从而复用许多共性功能。目前有 GenericServlet HttpServlet 这两个类实现了 Servlet 接口。

大多数情况下,开发者只需要继承 HttpServlet 去实现自己的 Servlet 即可。

Servlet 基础接口定义了用于客户端请求处理的 service 方法。当有请求到达时,该方法由 servlet 容器路由到一个 servlet 实例。
Web 应用程序的并发请求处理通常需要 Web 开发人员去设计适合多线程执行的 Servlet,从而保证 service方法能在一个特定时间点处理多线程并发执行。(注:即 Servlet 默认是线程不安全的,需要开发人员处理多线程问题)
通常 Web 容器对于并发请求将使用同一个 servlet 处理,并且在不同的线程中并发执行 service 方法。

4.1 基于http规范的请求处理方法

HttpServlet 抽象子类在 Servlet 接口基础之上添加了些协议相关的方法,并且这些方法能根据 HTTP 请求类型自动的由 HttpServlet 中实现的 service 方法转发到相应的协议相关的处理方法上。

这些方法是:
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 编程都是类似。

 4.2 servlet实例个数

对于未托管在分布式环境中(默认)的 servlet 而言, servlet 容器对于每一个 Servlet 声明必须且只能产生一个实例。不过,如果 Servlet 实现了 SingleThreadModel 接口, servlet 容器可以选择实例化多个实例以便处理高负荷请求或者串行化请求到一个特定实例。
如果 servlet 以分布式方式进行部署,容器可以为每个虚拟机(JVM)的每个 Servlet 声明产生一个实例。但是,如果在分布式环境中 servlet 实现了 SingleThreadModel 接口,此时容器可以为每个容器的 JVM 实例化多个 Servlet 实例。

4.3 servlet生命周期

Servlet 是按照一个严格定义的生命周期被管理,该生命周期规定了 Servlet 如何被加载、实例化、初始化、处理客户端请求,以及何时结束服务。该声明周期可以通过 javax.servlet.Servlet 接口中的 initservice destroy 这些 API 来表示,

所有 Servlet 必须直接或间接的实现 GenericServlet HttpServlet 抽象类。

(1)加载和实例化

Servlet 容器负责加载和实例化 Servlet。加载和实例化可以发生在容器启动时,或者延迟初始化直到容器决定有请求需要处理时。当 Servlet 引擎启动后, servlet 容器必须定位所需要的 Servlet 类。 Servlet 容器使用普通的 Java 类加载设施加载 Servlet 类。

可以从本地文件系统或远程文件系统或者其他网络服务加载。加载完 Servlet 类后,容器就可以实例化它并使用了。

(2)初始化

一旦一个 Servlet 对象实例化完毕,容器接下来必须在处理客户端请求之前初始化该 Servlet 实例。初始化的目的是以便 Servlet 能读取持久化配置数据,初始化一些代价高的资源(比如 JDBC API 连接),或者执行一些一次性的动作。

容器通过调用 Servlet 实例的 init 方法完成初始化, init 方法定义在 Servlet 接口中,并且提供一个唯一的 ServletConfig 接口实现的对象作为参数,该对象每个 Servlet 实例一个。配置对象允许 Servlet 访问由 Web 应用配置信息提供的键-值对的初始化参数。

该配置对象也提供给 Servlet去访问一个 ServletContext 对象,ServletContext 描述了 Servlet 的运行时环境。请参考第 4 章,“Servlet Context”获取 ServletContext 接口的更多信息。

若初始化错误:

在初始化阶段, servlet 实现可能抛出 UnavailableException ServletException 异常。在这种情况下, Servlet不能放置到活动服务中,而且 Servlet 容器必须释放它。如果初始化没有成功, destroy 方法不应该被调用。
在 实 例 初 始 化 失 败 后 容 器 可 能 再 实 例 化 和 初 始 化 一 个 新 的 实 例 。 此 规 则 的 例 外 是 , 当 抛 出 的UnavailableException 表示一个不可用的最小时间,容器在创建和初始化一个新的 servlet 实例之前必须等待一段时间。

使用工具时的注意事项:

当一个工具加载并内省某个 Web 应用程序时触发的静态初始化,这种用法与调用 init 初始化方法是有区别的。在 Servlet init 方法没被调用,开发人员不应该假定其处于活动的容器环境内。比如,当某个 Servlet仅有静态方法被调用时,不应该与数据库或企业级 JavaBeanEJB)容器建立连接。

(3)请求处理

Servlet 完成初始化后, Servlet 容器就可以使用它处理客户端请求了。客户端请求由 ServletRequest 类型的request 对象表示。 Servlet 封装响应并返回给请求的客户端,该响应由 ServletResponse 类型的 response 对象表示。

这两个对象(request response)是由容器通过参数传递到 Servlet 接口的 service 方法的。在 HTTP 请 求 的 场 景 下 , 容 器 提 供 的 请 求 和 响 应 对 象 具 体 类 型 分 别 是 HttpServletRequest HttpServletResponse
需要注意的是,由 Servlet 容器初始化的某个 Servlet 实例在服务期间,可以在其生命周期中不处理任何请求。

(4)终止服务

Servlet 容器没必要保持装载的 Servlet 持续任何特定的一段时间。一个 Servlet 实例可能会在 servlet 容器内保持活跃(active)持续一段时间(以毫秒为单位), Servlet 容器的寿命可能是几天,几个月,或几年,或者是任何之间的时间。
Servlet 容器确定 servlet 应该从服务中移除时,将调用 Servlet 接口的 destroy 方法以允许 Servlet 释放它使用的任何资源和保存任何持久化的状态。例如,当想要节省内存资源或它被关闭时,容器可以做这个。
servlet 容器调用 destroy 方法之前,它必须让当前正在执行 service 方法的任何线程完成执行,或者超过了服务器定义的时间限制。
一旦调用了 servlet 实例的 destroy 方法,容器无法再路由其他请求到该 servlet 实例了。如果容器需要再次使用该 servlet,它必须用该 servlet 类的一个新的实例。在 destroy 方法完成后, servlet 容器必须释放 servlet实例以便被垃圾回收
终止服务终止服务

原文地址:https://www.cnblogs.com/ouym/p/7220270.html