用Servlet可以創建協議、平台無關的Web應用程序,Applet運行於浏覽器的JRE中,而Servlet則運行於Web應用服務器的Servlet容器中,Servlet沒有用戶圖形界面,Servlet和Web應用服務器的Servlet容器交互以接收請求返回響應。請求最先由Web應用服務器的Servlet容器處理並傳給Servlet,Servlet通過Web應用服務器返回響應給客戶端。客戶端程序可以使用任何可向Web應用服務器發送請求的語言開發。
Servlet最大的優勢在於它的高性能,Servlet采用了和CGI截然不同的運行方式,首先Servlet在第一次初始化時裝載並駐留在內存中,以後直接從內存中運行;其次,在默認情況下Servlet以單實例多線程的方式工作,一個新請求到達後,Servlet實例開啟一個新的線程服務這個請求。
Servlet 結構和線程安全
所有的Servlet都直接或間接地實現Javax.servlet.Servlet接口,這些接口規定了Servlet如何與Servlet容器進行通訊的方法,此外還定義了Servlet的生命周期。GenericServlet是和協議無關的通用Servlet,HttpServlet是專門針對HTTP協議開發的Servlet,Web應用程序的Servlet都直接繼承HttpServlet。其類的繼承體系如下圖所示:
圖1 Servlet的類繼承體系
javax.servlet.Servlet接口包括了3個控制Servlet生命周期的方法,它們分別是:
·init(ServletConfig config)方法
當Servlet初始化時,init()方法被調用執行初始化Servlet的工作,init()方法只被調用一次。Servlet初始化後就進入就緒態,隨時准備響應客戶端的請求。
·service(ServletRequest req, ServletResponse resp)方法
Servlet容器調用service()方法處理請求並返回響應。ServletRequest和ServletResponse作為入參傳給service(),ServletRequest封裝了請求的信息而ServletResponse封裝了響應的信息。
·destroy()方法
Servlet容器可以在任何時候卸載Servlet,此時destory()被調用,你可以在這兒釋放Servlet所占用的資源。
而javax.servlet.http包中的類用於支持HTTP協議,創建HTML網頁。HTTP協議是基於請求/響應工作模式,這些HTTP的請求方式包括:
GET
POST
PUT
DELETE
HEAD
TRACE
CONNECT
OPTIONS
javax.servlet.http.HttpServlet定義了多個服務HTTP協議的方法,這些方法名為doXxx()的樣式命名和HTTP請求方式名相呼應:如HTTP GET請求方式對應doGet(),而HTTP POST對應doPost()等。HttpServlet最初以service(HttpServletRequest req, HttpServletResponse resp)響應客戶端請求,並依據HTTP的請求方式調用相應的doXxx()方法來處理。
一般的,你僅需要覆蓋doGet()或doPost()方法,如果希望得到更多的控制,你也可以覆蓋doPut()和doDelete()方法,其他的方法一般很少使用。如果你使用JBuilder的Servlet向導,你可以具體指定創建哪些方法。
特別需要指出的是Servlet是以多線程的方式工作的,Servlet可以同時處理多個請求。作為開發人員,需要注意Servlet成員變量的線程安全,在doGet()、doPost()中的局部域變量是線程安全的,而Servlet的成員變量則有線程安全的隱患。所以除非你有意需要應用這種特性,在一般情況下,不宜將一些可改寫的變量定義成Servlet的成員變量,否則一定要采取線程同步的措施確保線程安全。
Servlet的特性及適用場合
雖然Servlet也可以用於生成動態網頁,但這個功能已經逐漸讓位給新銳JSP了,不過Servlet並沒有因為江山代有才人而成為Java歷史博物館的古董,它依然身懷絕技笑傲江湖:
·自動啟動
一般情況下,JSP只有在客戶端第一次調用後,方才進行編譯並初始化,而Servlet則可以通過web.XML的<load-on-startup>配置,使其在Web容器啟動時自動初始化。可使用Servlet這個特性完成Web應用程序的初始化工作:如下載字典表、控制表、初始化配置信息等,啟動某個後台進程等。
·路徑匹配映射
Servlet可以通過web.xml 中<servlet-mapping>用通配符配置URI映射,對多個匹配的URI進行響應,而JSP只能通過一個具體的URI調用。這個特性可以使你在請求進入某個具體的頁面前截獲並處理它,許多Web應用框架,如Struts、Spring都利用了Servlet的這個特性,在此基礎上創建構架。
·Servlet過濾器
Servlet過濾器繼承於javax.servlet.Servlet並實現javax.servlet.Filter的類,在請求到達服務程序前和響應發往客戶端前進行加工處理。如果有大量的頁面都需要進行相同的處理,則可以使用一個Servlet過濾器對此一並處理。如你可以用Servlet過濾器進行編碼轉換、或者為每個頁面添加一個統一的標題頭等。
·Servlet監聽器
J2EE定義了多個Web事件監聽器接口,Servlet監聽器是繼承javax.servlet.Servlet並實現這些事件監聽接口的類。如果Web應用服務器對某個Web容器的事件感興趣,就可以構造一個實現該事件監聽接口的Servlet,以便在該事件發生時做相應的處理。靈活使用Servlet監聽器,可以使一些原來很難實現的操作變得易如反掌。
此外,如果一個動態網頁的頁面展現邏輯少,而業務處理邏輯多,如一個計算圓周率並返回結果頁面的請求,這時使用Servlet比JSP更適合。所以需要創建一個動態網頁,在到底使用Servlet還是JSP的問題上舉棋不定時,請這記住下面這句經典的話:Servlet是包含HTML代碼的Java程序,而JSP是包含Java代碼的HTML網頁。