gavanwanggw

导航

how tomcat works 总结

希望各位网友在看完<<how tomcat works>>一书或者鄙人的tomcat专栏文章后再看这篇博客

这里主要是梳理各个章节的核心概念

第一章 一个简单的Webserver

第1章从这本书一開始就介绍了一个简单的HTTPserver。

要建立一个可工作的HTTPserver。你须要知道在 java.net 包里边的 2 个类的内部运作:Socket 和 ServerSocket。

这里有关于这 2个类足够的背景资料,使得你可以理解附带程序是怎样工作的。

类图例如以下:


程序的main方法中,建立HttpServer,调用await方法,从ServerSocket中取得inputstream与outputstream分别传递给Request类与Response类,最后调用Response的sendStaticResource方法.静态资源的处理方法就是,在默认的文件路径下依照分析出来的uri读取相应的文件,然后再调用outputstream的write方法。



第二章 一个简单的servlet容器

第一章的程序,仅仅能处理静态资源,这一章的程序就能处理简单的servlet。

第 2 章说明简单的 servlet 容器是怎样工作的。这一章带有 2 个 servlet 容器应用。能够处理静态资源和简单的 servlet 请求。尤其是你将会学到怎样创建 request 和 response 对象。然后把它们传递给被请求的 servlet 的 service 方法。

在 servlet 容器里边另一个 servlet,你能够从一个 web 浏览器中调用它。

类图例如以下:

核心代码例如以下:


HttpServer有两个处理器,分别为ServletProcessor与StaticResourceProcessor。究竟使用哪个,取决于分析到的uri的开头。


在ServletProcessor中,会指定默认的文件路径,路径下有servlet的class文件,我们用URLClassLoader载入从uri中分析得到的servletname,得到servlet后,调用service方法就可以。


在StaticResourceProcessor中,直接调用Response的sendStaticResource方法。
只是这里有些问题
Request方法会作为參数被传递到servelt中,而Request类里面有public型的parse方法与sendStaticResource方法,可是这两个方法不应该在servlet中被调用!总不能把两个方法改为private吧.一种方法是将两个方法的訪问限制符置空,就是默认的限制符,它是不能在包外被訪问的。
只是还有还有一种方法,门面模式

例如以下图:


RequestFacade类接收一个Request对象传递给其成员变量ServletRequest,
public class RequestFacade implements ServletRequest {

  private ServletRequest request = null;

  public RequestFacade(Request request) {
    this.request = request;
  }

  /* implementation of the ServletRequest*/
  public Object getAttribute(String attribute) {
    return request.getAttribute(attribute);
  }
}
看到了吧,RequestFacade仅仅是一个二传手,只是里面根本就没有parse方法。所以把RequestFacade作为參数传递给servlet是安全的。


所以,以后什么地方要用parse方法,就给它传Request对象;不能用parse的地方就传RequestFacade。

第三章 连接器

第3章介绍了一个简化版本号的Tomcat 4默认连接器。这章里边的程序提供了一个学习工具。用于理解第 4 章里边的讨论的连接器。

本章类图


这里的HttpConnector做的工作就创建一个套接字,然后传递给HttpProcessor,在HttpProcessor的process方法中
      parseRequest(input, output);
      parseHeaders(input);
以上两个方法是最重要的;
这一章最复杂的地方事实上在于解析HTTP请求
能够分为5步:
读取套接字的输入流;
解析请求行
解析请求头
解析cookie
获取參数
后面的代码例如以下:
      parseRequest(input, output);
      parseHeaders(input);

      //check if this is a request for a servlet or a static resource
      //a request for a servlet begins with "/servlet/"
      if (request.getRequestURI().startsWith("/servlet/")) {
        ServletProcessor processor = new ServletProcessor();
        processor.process(request, response);
      }
      else {
        StaticResourceProcessor processor = new StaticResourceProcessor();
        processor.process(request, response);
      }
分析完http请求,把它交给ServletProcessor或者StaticResourceProcessor就可以。

第四章 tomcat默认的连接器

第 4 章介绍了 Tomcat 4 的默认连接器。这个连接器已经不推荐使用。推荐使用一个更快的连接器。Coyote。

只是。默认的连接器更简单,更易于理解。


在这一章里,即引入了连接器的概念,也引入了容器的概念。咱们慢慢说,先看uml图。


先说连接器,在第三章的简易连接器里,我们仅仅有一个HttpProcessor,在这一章里,我们有了一个Processor连接池,这种优点就是我们同一时候能够处理多个请求了!
还有一方面,这里在解析请求头的时候,使用的是字符数组来取代字符串。为什么?效率高?效率为什么高?自己看源代码找资料。(我怎么认为自己好赖皮呀)
这里newProcessor与createProcessor的差别在于
newProcessor一定会产生一个新的HttpProcessor;
而createProcessor大部分情况是从processor池中拿;
httpprcessor启动后,(在run方法中)会调用
  process(socket);
待通过分析socket,把httprequest填充完成后,
connector.getContainer().invoke(request, response);

连接器的任务就算是完毕了!


这一节的容器是simplecontainer,它的invoke干的事情,事实上就是前面几章里ServletProcessor类里process()方法干的事情,通过urlclassloader载入类,调用载入类的service方法。

后面几章的内容,咱们明天接着说。


posted on 2017-04-12 17:52  gavanwanggw  阅读(201)  评论(0编辑  收藏  举报