Web 容器: 早期的web應(yīng)用主要是瀏覽靜態(tài)頁面耕突,想Apache, Nginx 都是向瀏覽器返回html文件喳资,然后瀏覽器解析并展示html文件。
后來隨著網(wǎng)絡(luò)的發(fā)展两曼,人們希望可以有更多的交互澳窑,即希望服務(wù)器不是簡單的返回一個html,而是可以根據(jù)用于的輸入斧散,動態(tài)的生成html來和用戶交互,所以這時我們就需要在服務(wù)器端再部署一下java程序來和用戶交互摊聋,這些程序就是servlet鸡捐,但是servlet 沒有main函數(shù),不能獨立運行麻裁,需要servlet容器來對他們進(jìn)行調(diào)度箍镜,所以就有了servlet容器。 像tomcat, jetty其實就是 HTTP服務(wù)器+ servlet容器
Apache是一個HTTP服務(wù)器煎源,而Tomcat或者Jetty是一個HTTP服務(wù)器+Servlet容器色迂。HTTP服務(wù)器與Servlet容器的功能界限是:你可以把HTTP服務(wù)器想象成前臺的接待,負(fù)責(zé)網(wǎng)絡(luò)通信和解析請求手销,而Servlet容器是業(yè)務(wù)部門歇僧,負(fù)責(zé)處理業(yè)務(wù)請求。
如下圖所示锋拖,HTTP服務(wù)器诈悍,負(fù)責(zé)獲取客戶端請求,然后將請求解析并發(fā)送給Servlet服務(wù)器兽埃,servlet容器決定具體調(diào)用那個servlet來執(zhí)行該請求侥钳。servlet怎么知道調(diào)用那個類的那個方法來處理請求呢?怎么知道每個方法的名字是啥讲仰,參數(shù)是啥呢慕趴? 很現(xiàn)實servlet容器和servlet之間必須有個接口來統(tǒng)一調(diào)度,這個接口就是servlet接口鄙陡。
servlet接口如下
public interface Servlet {
void init(ServletConfig config) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
String getServletInfo();
void destroy();
}
其中的init 方法可以在啟動servlet的時候初始化一些資源冕房; destroy則是在servlet銷毀時釋放一些資源。
getServletConfig則指夾在我們在web.xml中配置的一些參數(shù)趁矾。
service則是實現(xiàn)具體業(yè)務(wù)邏輯的地方耙册。
有接口通常就會有一個抽象類來實現(xiàn)一些通用邏輯,這里的抽象類則是GenericServlet. 雖然servlet并不在意請求時通過什么協(xié)議傳過來的毫捣,結(jié)果需要使用什么協(xié)議傳出去详拙,但是通常都是基于HTTP協(xié)議,所以為了方便使用這里還是實現(xiàn)了HTTPServlet,以加入http特性蔓同,我們?nèi)闇弦獙崿F(xiàn)http相關(guān)的servlet可以直接繼承該子類饶辙,然后重新doGet, doPost即可,大大簡化了我們編程斑粱。
下面我們再來看一下請求處理過程:
HTTP服務(wù)器拿到客戶端請求之后將其解析打包成一個ServletRequest,然后調(diào)用Servlet的service方法弃揽,將請求傳遞給Servlet容器, Servelt容器则北,根據(jù)提前制定好的映射規(guī)則矿微,根據(jù)請求中的URL 調(diào)用指定的servlet,如果servlet還沒有被加載尚揣,則通過反射機制將其加載到Servlet容器中涌矢,然后調(diào)用。調(diào)用完成之后將結(jié)果打包成ServletResponse返給HTTP服務(wù)器快骗,http服務(wù)器在將其解析打包成滿足http協(xié)議的數(shù)據(jù)包發(fā)送給客戶端娜庇。
那么我們一定很好奇,servlet容器怎么知道去哪里找我們的servlet類呢方篮?我們通常是以web服務(wù)的形式來注冊servlet思灌,web應(yīng)用程序通常有制定的目錄結(jié)構(gòu),如果大家都遵從這個目錄結(jié)構(gòu)恭取,那servlet容器就知道去哪里找我們的servlet類了泰偿。
web應(yīng)用程序的目錄結(jié)構(gòu)如下
通常一個web應(yīng)用程序會包含多個servlet。 servlet規(guī)范中定義了一個serveltContext來對應(yīng)這個web應(yīng)用程序蜈垮。其中可以存放一些公共信息耗跛,servlet之間也可以通過它來進(jìn)行交互。