——每天的寥寥几笔,坚持下去,将会是一份沉甸甸的积累。
《How tomcat works》前两章还是比较简单的,但第三章起就开始有些难度了,今天鉴于还有其他任务,就写一章的学习笔记吧(关于第三章——连接器)。。。
1.首先我们必须明白,不论tomcat的源码有多复杂,其实简化下来就两部分:
其一,解析Socket中获得的inputstream字节流,然后存储到request中(也就是说服务端读取并存储了客户端传来的信息)【这一大串工作,我们可以理解成连接器做的事,将HTTP的东西连接到本地对象中,个人想法】;
其二,就是根据解析结果,调用相关的处理程序处理最后返回,最常见的就是调用servlet处理。
然后上面最复杂(就前三章来讲)的就是将字节流存储到request中。因为这将是一个非常复杂的HTTP消息解析过程,它需要将请求行(请求方式,Uri资源,Uri参数,协议)、头部(cookies等)一一解析出来。
2.明白了上面两个步骤,那让我们来看看第三章的包结构:(相关源码+书籍下载下载:http://pan.baidu.com/s/1ntBhXX3)
connector: RequestStream,ResponseStream,ResponseWriter
connnectot.http:HttpConnector,HttpProcessor//前者用于创建serverSocket,监听客户端请求;后者是个关键类,后面单独讲
HttpRequest,HttpResponse,HttpRequestFacade,HttpResponseFacade
//request和response实现了HttpRequestServlet和HttpResponseServlet接口,相关填充数据由下面两个对象提供
HttpHeader,HttpRequestLine//HTTP消息的头部,请求行封装出的两个实体类
SocketInputStream//用Socket.InputStream封装出的新的类,实现了读取HTTP消息的头部和请求行,封装到上面两个对象中
Constants//存一些常量,降低耦合度,便于修改
core: servletProcessor,staticResourceProcessor
//这两个类为业务处理类,就servlet而言,会根据connector解析出的处理类类名,用反射机制实例化某servlet类来处理。
3.HttpProcessor(包含了上述整个流程)
public void process(Socket socket) {SocketInputStream input = null;OutputStream output = null;
try {
SocketInputStream input = null;
OutputStream output = null;
try {
input = new SocketInputStream(socket.getInputStream(), 2048);//封装出SocketInputStream对象,该对象实现了获取字节流中的请求行和头部的函数——readRequestLine()、readHeader()
output = socket.getOutputStream();
// create HttpRequest object and parse
request = new HttpRequest(input);//和前一篇文章一样
// create HttpResponse object
response = new HttpResponse(output);//同上
response.setRequest(request);//同上
parseRequest(input, output);//调用input的readRequestLine()获得请求行,然后封装到HttpRequest对象中进行解析,最后写到request对象中
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);
}
// Close the socket
socket.close();
// no shutdown for this application
}
catch (Exception e) {
e.printStackTrace();
}
}