Tomcat4源代码下载地址:http://pan.baidu.com/s/1qXKfbjQ
本节将对上一节对程序做修改,使用连接器的作用:创建request和response对象,并将它们作为servlet接口的service()方法的参数传入;解析Http请求头,使servlet实例能够获取到请求头、cookie和请求参数等信息。
从本节开始,所有的程序都会按照模块进行划分,本章的应用程序包含3个模块:连接器模块、启动模块和核心模块。
连接器模块中的类,包括:1、连接器及其支持类(HttpConnector和HttpProcessor);
2、表示HTTP请求的类(HttpRequest)及其支持类;
3、表示HTTP响应的类(HttpResponse)及其支持类;
4、外观类(HttpRequestFacade和HttpResponseFacade);
5、常量类(Constant)。
核心模块包含:ServletProcessor类和StaticResourceProcessor类。
启动模块包含一个类:Bootstrap类。
以下是本节程序简化的UML类图:
本节程序的包结构如下:
整个程序从Bootstrap启动,新起一个线程运行HttpConnector,HttpConnector运行时序简图图如下:
SocketInputStream是java.io.InputStream的包装类,包含两个重要的方法:readRequestLine和readHeader。
readRequestLine:读取http请求第一行,包含,URI、请求方法和HTTP版本信息(将这些信息全部以HttpRequestLine类的形式封装)。
readHeader:读取请求头信息,每次调用readHeader方法都会返回一个名/值对(将这些信息以HttpHeader类的形式封装)。
在HttpProcessor中,首先会构造一个HttpRequestLine实例,但是在这个实例中没有包含任何信息,通过HttpProcessor的parseRequest(input, output)将http请求的第一行传递给刚才的HttpRequestLine实例。
通过HttpProcessor的parseHeaders(SocketInputStream input)方法,循环读取http请求中所有请求头信息,最后将请求头的名/值通过HttpRequest的addHeader(String name, String value)方法放入一个HashMap中。