希望各位网友在看完<<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 浏览器中调用它。
核心代码例如以下:
在ServletProcessor中,会指定默认的文件路径,路径下有servlet的class文件,我们用URLClassLoader载入从uri中分析得到的servletname,得到servlet后,调用service方法就可以。
在StaticResourceProcessor中,直接调用Response的sendStaticResource方法。
只是这里有些问题
Request方法会作为參数被传递到servelt中,而Request类里面有public型的parse方法与sendStaticResource方法,可是这两个方法不应该在servlet中被调用!总不能把两个方法改为private吧.一种方法是将两个方法的訪问限制符置空,就是默认的限制符,它是不能在包外被訪问的。
只是还有还有一种方法,门面模式
例如以下图:
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方法。
后面几章的内容,咱们明天接着说。