服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

servlet 容器的工作原理 ( 一 )


  本文介绍一个简单 servlet 容器的基本原理。现有两个 servlet 容器,第一个很简单,第二个则是根据第一个写出。为了使第一个容器尽量简单,所以没有做得很完整。复杂一些的 servlet 容器 (包括 tomcat 4 和 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 接口有五个方法,如下:
  
  • 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()
  
  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 对象,并发送字符串到浏览器。
  
  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("init");
    }
  
    public void service(servletrequest request, servletresponse response) throws servletexception, ioexception {
      system.out.println("from service");
      printwriter out = response.getwriter();
      out.println("hello.roses are red.");
      out.print("violets are blue.");
    }
  
    public void destroy() {
      system.out.println("destroy");
    }
  
    public string getservletinfo() {
      return null;
    }
  
    public servletconfig getservletconfig() {
      return null;
    }
  }
  
  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命令和前文是一样的。

扫描关注微信公众号