相信大多 Web 開(kāi)發(fā)者對(duì) Tomcat 是非常熟悉的,眾所周知 Tomcat 是一款非常好用的開(kāi)源 Servlet 容器,您一定對(duì)這個(gè)最流行的 Servlet 容器充滿好奇,雖然它并不像一個(gè)黑盒子那樣讓人無(wú)法觸摸但是 Tomcat 的源碼的確讓人看起來(lái)頭疼。筆者就在這里和大家共同分析一個(gè)簡(jiǎn)單的 Web服務(wù)器是如何工作的源碼 下載地址 。
Web服務(wù)器
Web服務(wù)器 是一個(gè)復(fù)雜的系統(tǒng),一個(gè) Web服務(wù)器 要為一個(gè) Servlet 的請(qǐng)求提供服務(wù),需要做三件事:
1 、創(chuàng)建一個(gè) request 對(duì)象并填充那些有可能被所引用的 Servlet 使用的信息,如參數(shù)、頭部、 cookies 、查詢字符串等等。一個(gè) request 對(duì)象是 javax.servlet.ServletRequest 或 javax.servlet.http.ServletRequest 接口的一個(gè)實(shí)例
2 、創(chuàng)建一個(gè) response 對(duì)象,所引用的 servlet 使用它來(lái)給客戶端發(fā)送響應(yīng)。一個(gè) response 對(duì)象是 javax.servlet.ServletRequest 或 javax.servlet.http.ServletRequest 接口的一個(gè)實(shí)例。
3 、調(diào)用 servlet 的 service 方法,并傳入 request 和 response 對(duì)象。這里 servlet 會(huì)從 request 對(duì)象取值,給 response 寫值。
在正式展示代碼之前還需要了解一些必須額 HTTP 的知識(shí)(如果您對(duì)此非常熟悉您可以直接看下面分析代碼)
HTTP
HTTP 的定義不知道的童鞋可以自己去度娘,這里主要要說(shuō)的就是 HTTP 協(xié)議的格式
HTTP 請(qǐng)求包括三部分
1 、方法、統(tǒng)一資源標(biāo)識(shí)符( URI )、協(xié)議 / 版本
2 、請(qǐng)求的頭部
3 、主題內(nèi)容
下面是一個(gè) HTTP 請(qǐng)求的例子
第一行表明這是 POST 請(qǐng)求方法, /examples/default.jsp 是 URI , HTTP/1.1 是協(xié)議以及版本。其中 URI 指明了一個(gè)互聯(lián)網(wǎng)資源,這里通常是相對(duì)服務(wù)器根目錄解釋的,也就是說(shuō)這個(gè) HTTP 請(qǐng)求就是告訴服務(wù)器我需要這個(gè)文件目錄如下:根目錄 / examples/default.jsp 。
最后一行是 HTTP 的主題內(nèi)容, Servlet 會(huì)處理請(qǐng)求的主題內(nèi)容,然后返回給客戶端 HTTP 響應(yīng)。
類似于 HTTP 請(qǐng)求,一個(gè) HTTP 響應(yīng)也包括上面三個(gè)部分。
1 、方法、統(tǒng)一資源標(biāo)識(shí)符( URI )、協(xié)議 / 版本
2 、響應(yīng)的頭部
3 、主題內(nèi)容
下面是一個(gè) HTTP 響應(yīng)的例子
第一行告訴協(xié)議版本,以及請(qǐng)求成功( 200 表示成功)
響應(yīng)頭部和請(qǐng)求頭部一樣,一些有用的信息。響應(yīng)的主體就是響應(yīng)本身 HTML 內(nèi)容。
好了基本知識(shí)介紹完畢,下面開(kāi)始解釋代碼
部分相關(guān)代碼
HttpServer 類代表一個(gè) web 服務(wù)器。首先提供一個(gè) WEB_ROOT 所在的目錄和它下面所有的子目錄下靜態(tài)資源。其次定義了一個(gè)中止服務(wù)的命令,也就是說(shuō)當(dāng)?shù)玫降恼?qǐng)求后面跟 /shutdown 的時(shí)候停止服務(wù),默認(rèn)是把服務(wù)設(shè)置為開(kāi)啟。下面就是進(jìn)入 main 函數(shù)了,首先實(shí)例化一個(gè) HttpServer 類,然后就是通過(guò) await 方法等待客戶端發(fā)來(lái)的請(qǐng)求。如果客戶端輸入的 URL 不是 http://localhost:8080/SHUTDOWN 則表示不停止服務(wù)器,然后就是繼續(xù)執(zhí)行 await 方法中的內(nèi)容,在 await 方法中最重要的就是定義兩個(gè)對(duì)象,一個(gè)是 request 一個(gè)是 response ,下面就來(lái)說(shuō)說(shuō) Request 和 Response 類。
首先調(diào)用 InputStream 對(duì)象中的 read 方法獲取 HTTP 請(qǐng)求的原始數(shù)據(jù),然后在 parseUri 方法中獲得 uri 也就是要請(qǐng)求的靜態(tài)資源。說(shuō)白了 Request 類的主要作用就是告訴服務(wù)器用戶要的是什么也就是在 http://localhost:8080 后面出現(xiàn)的東西。
Response 類代表一個(gè) HTTP 響應(yīng)。首先 Response 接收一個(gè) OutputStream 對(duì)象,然后通過(guò) sendStaticResource 方法對(duì)接收的 Request 進(jìn)行處理,整個(gè)處理過(guò)程就是根據(jù)請(qǐng)求在服務(wù)器端進(jìn)行尋找對(duì)應(yīng)靜態(tài)資源的過(guò)程。找到所需要的資源后發(fā)送給客戶端然后讓客戶端顯示出來(lái)。
運(yùn)行程序
運(yùn)行上面的 HttpServer 類,然后在瀏覽器的地址欄中鍵入下面的地址: http:localhost:8080/index.jsp ,然后你會(huì)在瀏覽器中看到 index.jsp 頁(yè)面。
在控制臺(tái)可以看到類似于下面的 HTTP 請(qǐng)求
小結(jié)
上面自己動(dòng)手寫的這個(gè)所謂的服務(wù)器僅僅有三個(gè)類組成,從功能上來(lái)說(shuō)他只能顯示一些靜態(tài)的資源,并不是全部功能。一個(gè)優(yōu)秀的服務(wù)器還有很多細(xì)節(jié)要做,但是出于學(xué)習(xí)的目的大家現(xiàn)在有這些了解就足夠了,后面還會(huì)有對(duì)服務(wù)器的詳細(xì)介紹,敬請(qǐng)期待。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
