本文共 2580 字,大约阅读时间需要 8 分钟。
什么是 Servlet? Servlet 是用 Java 编写的服务器端程序,它与协议和平台无关。Servlet 运行于 Java-enabled Web Server 中。Java Servlet 可以动态地扩展服务器的能力,并采用请求-响应模式提供 Web 服务。 Servlet 可以被认为是服务器端的 applet。Servlet 被 Web 服务器加载和执行,就如同 applet 被浏览器加载和执行一样。Servlet 从客户端(通过 Web 服务器)接收请求,执行某种作业,然后返回结果。 由于 Servlet 是在服务器上执行,通常与 applet 相关的安全性的问题并不需实现。Servlet 使相当数量的不可能或者至少是很难由 applet 实现的功能的实现成为可能。与现有系统通过 CORBA,RMI,socket 和本地(native)调用的通信就是其中的一些例子。另外,一定要注意:Web 浏览器并不直接和 Servlet 通信,Servlet 是由 Web 服务器加载和执行的。这意味着如果你的 Web 服务器有防火墙保护,那么你的 Servlet 也将得到防火墙的保护。 为什么要使用 Servlet? 最起码,Servlet 可以很好地替代公共网关接口(Common Gateway Interface,CGI)脚本。通常 CGI 脚本是用 Perl 或者 C 语言编写的,它们总是和特定的服务器平台紧密相关。而 Servlet 是用 Java 编写的,所以它们一开始就是平台无关的。这样,Java 编写一次就可以在任何平台运行(write once, run anywhere)的承诺就同样可以在服务器上实现了。 Servlet 的生命周期 Servlet 运行在 Servlet 容器中,其生命周期由容器来管理。Servlet 的生命周期通过 javax.servlet.Servlet 接口中的 init(ServletConfig), service(ServletRequest, ServletResponse) 和 destroy() 方法来表示。 Servlet 的生命周期包含了下面四个阶段。 (1) 加载和实例化 Servlet 容器负责加载和实例化 Servlet。当 Servlet 容器启动时,或者在容器检测到需要这个 Servlet 来响应第一个请求时,创建 Servlet 实例。 对于 tomcat 而言,Servlet 的实例化和初始化的时机是:当容器检测到对该 Servlet 的第一次请求时。 (2) 初始化 在 Servlet 实例化之后,容器必须调用 Servlet 的 init 方法初始化这个对象。初始化的目的是为了让 Servlet 对象在处理客户端请求前完成一些初始化的工作。对于每一个 Servlet 实例,init 方法只能被调用一次。在初始化期间,Servlet 实例可以使用容器为它准备的 ServletConfig 对象从 Web 应用程序的配置信息(在 web.xml 中配置)中获取初始化的参数信息。在初始化期间,如果发生错误,Servlet 实例可以抛出 ServletException 异常或者 UnavailableException 异常来通知容器。ServletException 异常用于指明一般的初始化失败,此时请求该 Servlet 时会得到 500 错误,例如没有找到初始化参数;而 UnavailableException 异常用于通知容器该 Servlet 实例不可用,这种情况下请求该 Servlet 时会得到 404 错误。若在 init 方法中发生其它异常,请求该 Servlet 时同样会得到 500 错误。 (3) 请求处理 Servlet 容器调用 Servlet 的 service 方法对请求进行处理。要注意的是,在 service 方法调用之前,init 方法必须成功执行。在 service 方法中,Servlet 实例通过 ServletRequest 对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用 ServletResponse 对象的方法设置响应信息。在 service 方法执行期间,如果发生错误,Servlet 实例可以抛出 ServletException 异常或者 UnavailableException 异常。如果 UnavailableException 异常指示了该实例永久不可用,Servlet 容器将调用实例的 destroy 方法,释放该实例。此后对该实例的任何请求,都将收到容器发送的 HTTP 404(请求的资源不可用) 响应。如果 UnavailableException 异常指示了该实例暂时不可用,那么在暂时不可用的时间段内,对该实例的任何请求,都将收到容器发送的 HTTP 503(服务器暂时忙,不能处理请求) 响应。 (4) 服务终止 当容器检测到一个 Servlet 实例应该从服务中被移除的时候,容器就会调用实例的 destroy 方法,以便让该实例可用释放它所使用的资源。当需要释放内存或者容器关闭时,容器就会调用 Servlet 实例的 destroy 方法。在 destroy 方法调用之后,容器会释放这个 Servlet 实例,该实例随后会被 java 的垃圾回收器所回收。如果再次需要这个 Servlet 处理请求,Servlet 容器会创建一个新的 Servlet 实例。这里,容器会重新创建 Servlet 的实例并没有与 "对于每一个 Servlet 实例,init 方法只能被调用一次" 相违背,因为重新创建的 Servlet 实例已进入了一个新的生命周期,原来 Servlet 实例的生命周期已经结束。 在整个 Servlet 的生命周期过程中,创建 Servlet 实例、调用实例的 init 和 destroy 方法都只进行一次,当初始化完成后,Servlet 容器会将该实例保存在内存中,通过调用它的 service 方法,为接收到请求服务 转载于:https://my.oschina.net/liting/blog/474210