理解Servlet和Servlet容器、Web服務器等概念
轉載自http://blog.csdn.net/iAm333
之前在開源中國看到一篇文章《初學 Java Web 開發,請遠離各種框架,從 Servlet 開發》,覺得很不錯。想到自己之前一直對各種框架執迷不悟,頓感慚愧。於是,看了孫鑫的《Servlet/JSP深入詳解:基於Tomcat的Web開發》、林信良的《JSP&Servlet學習筆記(第二版)》以及網上其他一些相關的資料,將自己的理解整理如下。
Web技術
隨著互聯網技術的發展,基於HTTP和HTML的web應用急速增長。早期的web應用主要用於瀏覽新聞等靜態頁面,用戶通過HTTP協議請求服務 器上的靜態頁面,服務器上的web服務器軟件接收到請求後,讀取URI標示的資源,再加上消息報頭發送給客戶端瀏覽器,瀏覽器負責解析HTML,將結果呈 現出來。
然而隨著時間發展,用戶已經不滿足於僅瀏覽靜態頁面。用戶需要一些交互操作,獲取一些動態結果。如果基於HTTP協議實現服務器端軟件增強功能太過 復雜,所以需要一些擴展機制來實現用戶想要的功能。早期使用的Web服務器擴展機制是CGI(Common Gateway Interface,公共網關接口)。使用這種方法,用戶單擊某個鏈接或輸入網址來訪問CGI程序,web服務器收到請求後,運行該CGI程序,對用戶請 求進行處理,緊接著將處理結果並產生一個響應,該響應被返回給web服務器,web服務器對響應進行包裝,以HTTP響應的方式返回給瀏覽器。
CGI程序在一定程度上解決了用戶需求。不過還存在一些不足之處,如CGI程序編寫困難,響應時間較長,以進程方式運行導致性能受限。於是1997年,sun公司推出了Servlet技術,作為java陣營的CGI解決方案。
servlet與servlet容器
Java Servlet(Java服務器小程序)是一個基於Java技術的Web組件,運行在服務器端,它由Servlet容器所管理,用於生成動態的內容。 Servlet是平臺獨立的Java類,編寫一個Servlet,實際上就是按照Servlet規範編寫一個Java類。Servlet被編譯為平臺獨立 的字節碼,可以被動態地加載到支持Java技術的Web服務器中運行。
Servlet容器也叫做Servlet引擎,是Web服務器或應用程序服務器的一部分,用於在發送的請求和響應之上提供網絡服務,解碼基於 MIME的請求,格式化基於MIME的響應。Servlet沒有main方法,不能獨立運行,它必須被部署到Servlet容器中,由容器來實例化和調用 Servlet的方法(如doGet()和doPost()),Servlet容器在Servlet的生命周期內包容和管理Servlet。在JSP技術 推出後,管理和運行Servlet/JSP的容器也稱為Web容器。
(註:常用的MIME類型:text/html,application/pdf,video/quicktime,application /java,image/jpeg,application/jar,application/octet-stream,application/x- zip)
有了servlet之後,用戶通過單擊某個鏈接或者直接在瀏覽器的地址欄中輸入URL來訪問Servlet,Web服務器接收到該請求後,並不是將 請求直接交給Servlet,而是交給Servlet容器。Servlet容器實例化Servlet,調用Servlet的一個特定方法對請求進行處理, 並產生一個響應。這個響應由Servlet容器返回給Web服務器,Web服務器包裝這個響應,以HTTP響應的形式發送給Web瀏覽器。
servlet容器能提供什麽?
我們知道需要由servlet容器來管理和運行servlet,但是為什麽要這樣做呢?使用servlet容器的原因有:
通信支持:利用容器提供的方法,你能輕松的讓servlet與web服務器對話,而不用自己建立serversocket、監聽某個端口、創建流等 等。容器知道自己與web服務器之間的協議,所以你的servlet不用擔心web服務器(如Apache)和你自己的web代碼之間的API,只需要考 慮如何在servlet中實現業務邏輯(如處理一個訂單)。
生命周期管理:servlet容器控制著servlet的生與死,它負責加載類、實例化和初始化servlet,調用servlet方法,以及使servlet實例被垃圾回收,有了servlet容器,你不需要太多的考慮資源管理。
多線程支持:容器會自動為它所接收的每個servlet請求創建一個新的java線程。針對用戶的請求,如果servlet已經運行完相應的http服務方法,這個線程就會結束。這並不是說你不需要考慮線程安全性,其實你還會遇到同步問題,不過這樣能使你少做很多工作。
聲明方式實現安全:利用servlet容器,你可以使用xml部署描述文件來配置和修改安全性,而不必將其硬編碼寫到servlet類代碼中。
JSP支持:servlet容器負責將jsp代碼翻譯為真正的java代碼。
用與CGI程序相比,Servlet具有以下優點:
Servlet是單實例多線程的運行方式,每個請求在一個獨立的線程中運行,而提供服務的Servlet實例只有一個。
Servlet具有可升級性,能響應更多的請求,因為Servlet容器使用一個線程而不是操作系統進程,而線程僅占用有限的系統資源。
Servlet使用標準的API,被更多的Web服務器所支持。
Servlet使用Java語言編寫,因此擁有Java程序語言的所有優點,包括容易開發和平臺獨立性。
Servlet可以訪問Java平臺豐富的類庫,使得各種應用的開發更為容易。
Servlet容器給Servlet提供額外的功能,如錯誤處理和安全。
Servlet容器的分類
根據Servlet容器工作模式的不同,可以將Servlet容器分為以下三類:
1)獨立的Servlet容器
當我們使用基於Java技術的Web服務器時,Servlet容器作為構成Web服務器的一部分而存在。然而大多數的Web服務器並非基於Java,因此,就有了下面兩種Servlet容器的工作模式。
2)進程內的Servlet容器
Servlet容器由Web服務器插件和Java容器兩部分的實現組成。Web服務器插件在某個Web服務器內部地址空間中打開一個 JVM(Java虛擬機),使得Java容器可以在此JVM中加載並運行Servlet。如有客戶端調用Servlet的請求到來,插件取得對此請求的控 制並將它傳遞(使用JNI技術)給Java容器,然後由Java容器將此請求交由Servlet進行處理。進程內的Servlet容器對於單進程、多線程 的服務器非常適合,提供了較高的運行速度,但伸縮性有所不足。
3)進程外的Servlet容器
Servlet容器運行於Web服務器之外的地址空間,它也是由Web服務器插件和Java容器兩部分的實現組成的。Web服務器插件和Java容 器(在外部JVM中運行)使用IPC機制(通常是TCP/IP)進行通信。當一個調用Servlet的請求到達時,插件取得對此請求的控制並將其傳遞(使 用IPC機制)給Java容器。進程外Servlet容器對客戶請求的響應速度不如進程內的Servlet容器,但進程外容器具有更好的伸縮性和穩定性。
Tomcat
學習Servlet技術,就需要有一個Servlet運行環境,也就是需要有一個Servlet容器,本文用的是Tomcat。
Tomcat是一個免費的開放源代碼的Servlet容器,它是Apache軟件基金會(Apache Software Foundation)的一個頂級項目,由Apache、Sun和其他一些公司及個人共同開發而成。由於有了Sun的參與和支持,最新的Servlet和 JSP規範總是能在Tomcat中得到體現,Tomcat 6支持最新的Servlet 2.5和JSP 2.1規範。因為Tomcat技術先進、性能穩定,而且免費,因而深受Java愛好者的喜愛,並得到了部分軟件開發商的認可,成為目前比較流行的Web服 務器。
Tomcat和IIS、Apache等Web服務器一樣,具有處理HTML頁面的功能,另外它還是一個Servlet和JSP容器,獨立的 Servlet容器是Tomcat的默認模式。不過,Tomcat處理靜態HTML的能力不如Apache,我們可以將Apache和Tomcat集成在 一起使用,Apache作為HTTP Web服務器,Tomcat作為Web容器。
Tomcat服務器接受客戶請求並做出響應的過程如下:
1)客戶端(通常都是瀏覽器)訪問Web服務器,發送HTTP請求。
2)Web服務器接收到請求後,傳遞給Servlet容器。
3)Servlet容器加載Servlet,產生Servlet實例後,向其傳遞表示請求和響應的對象。
4)Servlet實例使用請求對象得到客戶端的請求信息,然後進行相應的處理。
5)Servlet實例將處理結果通過響應對象發送回客戶端,容器負責確保響應正確送出,同時將控制返回給Web服務器。
Tomcat的體系結構
Tomcat服務器是由一系列可配置的組件構成的,其中核心組件是Catalina Servlet容器,它是所有其他Tomcat組件的頂層容器。我們可以通過查看Tomcat安裝文件夾下的conf文件夾中的server.xml文件 來了解Tomcat各組件之間的層次關系。由於server.xml註釋太多,特簡化如下:
<?xml version=‘1.0‘ encoding=‘utf-8‘?> <Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost"> <Context path="" docBase="WORKDIR" reloadable="true"/> </Host> </Engine> </Service> </Server>
其中WORKDIR為你想要導入的項目路徑。我們下面簡單介紹一下各組件在Tomcat服務器中的作用。
(1)Server
Server表示整個的Catalina Servlet容器。Tomcat提供了Server接口的一個默認實現,這通常不需要用戶自己去實現。在Server容器中,可以包含一個或多個Service組件。
(2)Service
Service是存活在Server內部的中間組件,它將一個或多個連接器(Connector)組件綁定到一個單獨的引擎(Engine)上。在Server中,可以包含一個或多個Service組件。Service也很少由用戶定制,Tomcat提供了Service接口的默認實現,而這種實現既簡單又能滿足應用。
(3)Connector
連接器(Connector)處理與客戶端的通信,它負責接收客戶請求,以及向客戶返回響應結果。在Tomcat中,有多個連接器可以使用。
(4)Engine
在Tomcat中,每個Service只能包含一個Servlet引擎(Engine)。引擎表示一個特定的Service的請求處理流水線。作為一個Service可以有多個連接器,引擎從連接器接收和處理所有的請求,將響應返回給適合的連接器,通過連接器傳輸給用戶。用戶允許通過實現Engine接口提供自定義的引擎,但通常不需要這麽做。
(5)Host
Host表示一個虛擬主機,一個引擎可以包含多個Host。用戶通常不需要創建自定義的Host,因為Tomcat給出的Host接口的實現(類StandardHost)提供了重要的附加功能。
(6)Context
一個Context表示了一個Web應用程序,運行在特定的虛擬主機中。什麽是Web應用程序呢?在Sun公司發布的Java Servlet規範中,對Web應用程序做出了如下的定義:“一個Web應用程序是由一組Servlet、HTML頁面、類,以及其他的資源組成的運行在Web服務器上的完整的應用程序。它可以在多個供應商提供的實現了Servlet規範的Web容器中運行”。一個Host可以包含多個Context(代表Web應用程序),每一個Context都有一個唯一的路徑。用戶通常不需要創建自定義的Context,因為Tomcat給出的Context接口的實現(類StandardContext)提供了重要的附加功能。
理解Servlet和Servlet容器、Web服務器等概念