Servlet容器工作原理讲解(一)

本文介绍一个简单 servlet 容器的基本原理。现有两个servlet容器,第一个很简单,第二个则是根据第一个写出。为了使第一个容器尽量简单,所以没有做得很完整。复杂一些的servlet容器(包括TOMCAT4和5)在TOMCAT运行内幕的其他章节有介绍。


两个servlet容器都处理简单的servlet及staticResource。您可以使用 webroot/ 目录下的 PrimitiveServlet 来测试它。复杂一些的 servlet会超出这些容器的容量,您可以从 TOMCAT 运行内幕 一书学习创建复杂的 servlet 容器。


两个应用程序的类都封装在ex02.pyrmont 包下。在理解应用程序如何运作之前,您必须熟悉 javax.servlet.Servlet 接口。首先就来介绍这个接口。随后,就介绍servlet容器服务servlet的具体内容。


javax.servlet.Servlet 接口


servlet 编程,需要引用以下两个类和接口:javax.servlet 和 javax.servlet.http,在这些类和接口中,javax.servlet.Servlet接口尤为重要。所有的 servlet 必须实现这个接口或继承已实现这个接口的类。


Servlet 接口有五个方法,如下


<ccid_nobr>

<ccid_code>public void init(ServletConfig config) throws ServletException

public void service(ServletRequest request, ServletResponse response)
throws ServletException, java.io.IOException
public void destroy()
public ServletConfig getServletConfig()
public java.lang.String getServletInfo()</ccid_code>


</ccid_nobr>


init、service和 destroy 方法是 Servlet 生命周期的方法。当 Servlet 类实例化后,容器加载 init,以通知 servlet 它已进入服务行列。init 方法必须被加载,Servelt 才能接收和请求。如果要载入数据库驱动程序、初始化一些值等等,程序员可以重写这个方法。在其他情况下,这个方法一般为空。


service 方法由 Servlet 容器调用,以允许 Servlet 响应一个请求。Servlet 容器传递 javax.servlet.ServletRequest 对象和 javax.servlet.ServletResponse 对象。ServletRequest 对象包含客户端 HTTP 请求信息,ServletResponse 则封装servlet 响应。这两个对象,您可以写一些需要 servlet 怎样服务和客户怎样请求的代码。


从service中删除Servlet实例之前,容器调用destroy方法。在servlet容器关闭或servlet容器需要更多的内存时,就调用它。这个方法只有在servlet的service方法内的所有线程都退出的时候,或在超时的时候才会被调用。在 servlet 容器调用 destroy方法之后,它将不再调用servlet的service方法。destroy 方法给了 servlet 机会,来清除所有候住的资源(比如:内存,文件处理和线程),以确保在内存中所有的持续状态和 servlet的当前状态是同步的。Listing 2.1 包含了PrimitiveServlet 的代码,此servlet非常简单,您 可以用它来测试本文中的servlet容器应用程序。


PrimitiveServlet 类实现了javax.servlet.Servlet 并提供了五个servlet方法的接口 。它做的事情也很简单:每次调用 init,service 或 destroy方法的时候,servlet就向控制口写入方法名。service 方法也从ServletResponsec对象中获得java.io.PrintWriter 对象,并发送字符串到浏览器。


<ccid_nobr>

<ccid_code>Listing 2.1.PrimitiveServlet.java

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
public class PrimitiveServlet implements Servlet
{
public void init(ServletConfig config) throws ServletException
{
System.out.println(&quot;init&quot;);
}
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
{
System.out.println(&quot;from service&quot;);
PrintWriter out = response.getWriter();
out.println(&quot;Hello.Roses are red.&quot;);
out.print(&quot;Violets are blue.&quot;);
}
public void destroy()
{
System.out.println(&quot;destroy&quot;);
}
public String getServletInfo()
{
return null;
}

public ServletConfig getServletConfig()
{
return null;
}
}</ccid_code>


</ccid_nobr>


Application 1


现在,我们从 servlet容器的角度来看看 servlet 编程。一个功能健全的 servlet容器对于每个 servlet 的HTTP请求会完成以下事情:


当servlet 第一次被调用的时候,加载了 servlet类并调用它的init方法(仅调用一次)


响应每次请求的时候 ,构建一个javax.servlet.ServletRequest 和 javax.servlet.ServletResponse实例。


激活servlet的service方法,传递 ServletRequest 和 ServletResponse 对象。


当servlet类关闭的时候,调用servlet的destroy方法,并卸载servlet类。


发生在 servlet 容器内部的事就复杂多了。只是这个简单的servlet容器的功能不很健全,所以,这它只能运行非常简单的servelt ,并不能调用servlet的init和destroy方法。然而,它也执行了以下动作:


等待HTTP请求。


构建ServletRequest和ServletResponse对象


如果请求的是一个staticResource,就会激活StaticResourceProcessor实例的 process方法,传递ServletRequest 和 ServletResponse 对象。


如果请求的是一个servlet ,载入该类,并激活它的service方法,传递ServletRequest和ServletResponse 对象。注意:在这个servlet 容器,每当 servlet被请求的时候该类就被载入。


在第一个应用程序中,servlet容器由六个类组成 。


HttpServer1


Request


Response


StaticResourceProcessor


ServletProcessor1


Constants





证如前文中的应用程序一样,这个程序的进入口(静态 main 方法)是HttpServer 类。这个方法创建了HttpServer实例,并调用它的await方法。这个方法等待 HTTP 请示,然后创建一个 request 对象和 response对象,根据请求是否是staticResource还是 servlet 来分派它们到 StaticResourceProcessor实例或ServletProcessor实例。


Constants 类包含 static find WEB_ROOT,它是从其他类引用的。 WEB_ROOT 指明 PrimitiveServlet 位置 和容器服务的staticResource。


HttpServer1 实例等待 HTTP 请求,直到它收到一个 shutdown 命令。发布 shutdown命令和前文是一样的。


这个应用程序中的每一个类将在下节介绍。 
 
阅读更多
个人分类: java
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭