——每天的寥寥幾筆,堅持下去,將會是一份沉甸甸的積累。
《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();
}
}