Servlet是一種獨立於平台和協議的伺服器端的Java應用程式,可以產生動態Web頁面。
Servlet是位於Web 服務器內部的伺服器端的Java應用程式,與傳統的從命令列啟動的Java應用程式不同,Servlet由Web伺服器進行載入,該Web伺服器必須包含支援Servlet的Java虛擬機器。
Java Servlet 與 Applet 的比較:
相似之處:
* 它們不是獨立的應用程式,沒有main()方法。
* 它們不是由使用者或程式員調用,而是由另外一個應用程式(容器)調用。
* 它們都有一個生存周期,包含init()和destroy()方法。
不同之處:
* Applet具有很好的圖形介面(AWT),與瀏覽器一起,在用戶端運行。
* Servlet 則沒有圖形介面,運行在伺服器端。
Java Servlet 與 CGI(Common Gateway Interface) 的比較:
與傳統的CGI和許多其他類似CGI的技術相比,Java Servlet具有更高的效率,更容易使用,功能更強大,具有更好的可移植性,更節省投資。在未來的技術發展過程中,Servlet有可能徹底取代CGI。
* 高效
在傳統的CGI中,每個請求都要啟動一個新的進程,如果CGI程式本身的執行時間較短,啟動進程所需要的開銷很可能反而超過實際執行時間。而在Servlet中,每個請求由一個輕量級的Java線程處理(而不是重量級的作業系統進程)。
在傳統CGI中,如果有N個並發的對同一CGI程式的請求,則該CGI程式的代碼在記憶體中重複裝載了N次;而對於Servlet,處理請求的是N個線程,只需要一份Servlet類代碼。在效能最佳化方面,Servlet也比CGI有著更多的選擇。
* 方便
Servlet提供了大量的工具 + 生產力常式,例如自動地解析和解碼HTML表單資料、讀取和設定HTTP頭、處理Cookie、跟蹤工作階段狀態等。
* 功能強大
在Servlet中,許多使用傳統CGI程式很難完成的任務都可以輕鬆地完成。例如,Servlet能夠直接和Web伺服器互動,而普通的CGI程式不能。Servlet還能夠在各個程式之間共用資料,使得資料庫連接池之類的功能很容易實現。
* 可移植性好
Servlet用Java編寫,Servlet API具有完善的標準。因此,為IPlanet Enterprise Server寫的Servlet無需任何實質上的改動即可移植到Apache、Microsoft IIS或者WebStar。幾乎所有的主流伺服器都直接或通過外掛程式支援Servlet。
* 節省投資
不僅有許多廉價甚至免費的Web伺服器可供個人或小規模網站使用,而且對於現有的伺服器,如果它不支援Servlet的話,要加上這部分功能也往往是免費的(或只需要極少的投資)。
Java Servlet 與 JSP(JavaServer Pages) 的比較:
JavaServer Pages(JSP)是一種實現普通靜態HTML和動態HTML混合編碼的技術,JSP並沒有增加任何本質上不能用Servlet實現的功能。但是,在JSP中編寫靜態HTML更加方便,不必再用println語句來輸出每一行HTML代碼。更重要的是,藉助內容和外觀的分離,頁面製作中不同性質的任務可以方便地分開:比如,由頁面設計者進行HTML設計,同時留出供Servlet程式員插入動態內容的空間。
Java Servlet API 2.2 的類和介面組成兩個Java 包,即:javax.servlet 和 javax.servlet.http(還包括javax.servlet.jsp包,不在本篇文章討論範圍之內)。
javax.servlet 包提供了控制 Servlet 生命週期所必需的 Servlet 介面,是編寫 Servlet 時必須要實現的。
javax.servlet.http 包提供了從Servlet 介面派生出的專門用於處理 HTTP 要求的抽象類別和一般的工具類。所有的Servlet 對象都要實現Servlet 介面,大多數情況下是作為已經實現了Servlet 介面的javax.servlet.GenericServlet 和 javax.servlet.http.HttpServlet 這兩個抽象類別的子類來間接實現Servlet 介面。
javax.servlet 包定義的類和介面:
interface RequestDispatcher
//定義一種對象,用於從客戶接受請求,並將請求發送到伺服器上任何指定的資源,如一個Servlet 、JSP 或 HTML 檔案。
interface Servlet
//定義了所有 Servlet 必須實現的方法。
interface ServletConfig
//定義Servlet config 對象,由Servlet 引擎用在 Servlet 初始化時,向 Servlet 傳遞資訊。
interface ServletContext
//定義了一系列方法,以便Servlet與其啟動並執行環境通訊。
interface ServletRequest
//定義了用於向Servlet傳遞客戶請求資訊的對象。
interface ServletResponse
//定義了一個對象,由Servlet用於向客戶發送響應。
interface SingleThreadModel
//用於保證Servlet在任一時刻,只處理一個請求。
class GenericServlet
//繼承Servlet介面,定義了一個通用的,與協議無關的Servlet。
class ServletInputStream
//定義了一個輸入資料流,用於由Servlet從中讀取客戶請求的位元據。
class ServletOutputStream
//定義了一個輸出資料流,用於由Servlet向客戶發送位元據。
class ServletException
//定義了一個當Servlet遇到問題時可以拋出的異常。
class UnavailableException
//定義了一種異常,用於由Servlet指明它永遠或暫時不可用。
javax.servlet.http 包定義的類和介面:
interface HttpServletRequest
//繼承了ServletRequest 介面,為HTTPServlet 提供請求資訊。
interface HttpServletResponse
//繼承了ServletResponse 介面,為HTTPServlet 輸出響應資訊提供支援。
interface HttpSession
//為維護 HTTP 使用者的工作階段狀態提供支援。
interface HttpSessionBindingListener
//使得某對象在加入一個會話或從會話中刪除時能夠得到通知。
interface HttpSessionContext
//由Servlet 2.1 定義,該對象在新版本已不被支援。
class Cookie
//用在Servlet 中使用Cookie 技術
class HttpServlet
//定義了一個抽象類別,繼承 GenericServlet 抽象類別,應被 HTTPServlet 繼承。
class HttpSessionBindingEvent
//定義了一種對象,當某一個實現了HttpSessionBindingListener介面的對象被加入會話或從會//話中刪除時,會收到該類對象的一個控制代碼
class HttpUtils
//提供了一系列便於編寫HTTPServlet 的方法。
下面主要介紹javax.servlet.http提供的HTTP Servlet應用編程介面。
HTTP Servlet 使用一個 HTML 表格來發送和接收資料。要建立一個 HTTP Servlet,請擴充 HttpServlet 類, 該類是用專門的方法來處理 HTML 表格的 GenericServlet 的一個子類。 HTML 表單是由 <FORM> 和 </FORM> 標記定義的。表單中典型地包含輸入欄位(如文本輸入欄位、複選框、選項按鈕和挑選清單)和用於提交資料的按鈕。當提交資訊時,它們還指定伺服器應執行哪一個Servlet(或其它的程式)。 HttpServlet 類包含 init()、destroy()、service() 等方法。其中 init() 和 destroy() 方法是繼承的。
(1) init() 方法
在 Servlet 的生命期中,僅執行一次 init() 方法。它是在伺服器裝入 Servlet 時執行的。 可以設定管理員,以在啟動伺服器或客戶機首次訪問 Servlet 時裝入 Servlet。 無論有多少客戶機訪問 Servlet,都不會重複執行 init() 。
預設的 init() 方法通常是符合要求的,但也可以用定製 init() 方法來覆蓋它,典型的是管理伺服器端資源。 例如,可能編寫一個定製 init() 來只用於一次裝入 GIF 映像,改進 Servlet 返回 GIF 映像和含有多個客戶機請求的效能。另一個樣本是初始化資料庫連接。預設的 init() 方法設定了 Servlet 的初始化參數,並用它的 ServletConfig 對象參數來啟動配置, 因此所有覆蓋 init() 方法的 Servlet 應調用 super.init() 以確保仍然執行這些任務。在調用 service() 方法之前,應確保已完成了 init() 方法。
(2) service() 方法
service() 方法是 Servlet 的核心。每當一個客戶請求一個HttpServlet 對象,該對象的service() 方法就要被調用,而且傳遞給這個方法一個"請求"(ServletRequest)對象和一個"響應"(ServletResponse)對象作為參數。 在 HttpServlet 中已存在 service() 方法。預設的服務功能是調用與 HTTP 要求的方法相應的 do 功能。例如, 如果 HTTP 要求方法為 GET,則預設情況下就調用 doGet() 。Servlet 應該為 Servlet 支援的 HTTP 方法覆蓋 do 功能。因為 HttpServlet.service() 方法會檢查要求方法是否調用了適當的處理方法,不必要覆蓋 service() 方法。只需覆蓋相應的 do 方法就可以了。
當一個客戶通過HTML 表單發出一個HTTP POST請求時,doPost()方法被調用。與POST請求相關的參數作為一個單獨的HTTP 要求從瀏覽器發送到伺服器。當需要修改伺服器端的資料時,應該使用doPost()方法。
當一個客戶通過HTML 表單發出一個HTTP GET請求或直接請求一個URL時,doGet()方法被調用。與GET請求相關的參數添加到URL的後面,並與這個請求一起發送。當不會修改伺服器端的資料時,應該使用doGet()方法。
Servlet的響應可以是下列幾種類型:
一個輸出資料流,瀏覽器根據它的內容類型(如text/HTML)進行解釋。
一個HTTP錯誤響應, 重新導向到另一個URL、servlet、JSP。
(3) destroy() 方法
destroy() 方法僅執行一次,即在伺服器停止且卸裝Servlet 時執行該方法。典型的,將 Servlet 作為伺服器處理序的一部分來關閉。預設的 destroy() 方法通常是符合要求的,但也可以覆蓋它,典型的是管理伺服器端資源。例如,如果 Servlet 在運行時會累計統計資料,則可以編寫一個 destroy() 方法,該方法用於在未裝入 Servlet 時將統計數字儲存在檔案中。另一個樣本是關閉資料庫連接。
當伺服器卸裝 Servlet 時,將在所有 service() 方法調用完成後,或在指定的時間間隔過後調用 destroy() 方法。一個Servlet 在運行service() 方法時可能會產生其它的線程,因此請確認在調用 destroy() 方法時,這些線程已終止或完成。
(4) GetServletConfig()方法
GetServletConfig()方法返回一個 ServletConfig 對象,該對象用來返回初始化參數和ServletContext。ServletContext 介面提供有關servlet 的環境資訊。
(5) GetServletInfo()方法
GetServletInfo()方法是一個可選的方法,它提供有關servlet 的資訊,如作者、版本、著作權。
當伺服器調用sevlet 的Service()、doGet()和doPost()這三個方法時,均需要 "請求"和"響應"對象作為參數。"請求"對象提供有關請求的資訊,而"響應"對象提供了一個將響應資訊返回給瀏覽器的一個通訊途徑。
javax.servlet 軟體包中的相關類為ServletResponse和ServletRequest,而javax.servlet.http 軟體包中的相關類為HttpServletRequest 和 HttpServletResponse。
Servlet 通過這些對象與伺服器通訊並最終與客戶機通訊。Servlet 能通過調用"請求"對象的方法獲知客戶機環境,伺服器環境的資訊和所有由客戶機提供的資訊。Servlet 可以調用"響應"對象的方法發送響應,該響應是準備發回客戶機的。