Servlet是Java提供的用于開發(fā)Web服務器應用程序的一個組件,運行在服務器端,由Servlet容器所管理,用于生成動態(tài)的內容。Servlet是平臺獨立的Java類,編寫一個Servlet,實際上就是按照Servlet規(guī)范編寫一個Java類。
如圖所示,Java提供一系列接口類(所謂接口類就是類中所有方法只提供方法聲明,不提供任何的方法實現(xiàn),這些類的實現(xiàn)就留給后繼者去做。):Servlet、ServletConfig、Serializable,然后通過多重繼承產生一個最通用的Servlet實現(xiàn)類(圖中Gerneric Servlet類),接下來,通過一個多重繼承與實現(xiàn),產生一個新的實現(xiàn)類HttpServlet,用戶在開發(fā)Servlet程序時只需繼承這個類,從而產生一個自己的類(圖中Hello_Servlet類),然后根據(jù)實際開發(fā)功能與信息處理需要,去實現(xiàn)該類中的相關方法即可。這就是前面提到的按照Servlet規(guī)范編寫一個Java類,從而編寫一個Servlet。 至于JSP(JavaServlet Page)從圖中可以看出,實際上它也是從Servlet繼承而來。只不過它在Servlet當中又添加/修改了一些方法,作了新的封裝。具體到Tomcat Web應用服務器中,它通過一個多重繼承,分別從Java的HttpJspPage和HttpServlet兩個類那里繼承和實現(xiàn)一些方法,然后封裝一個叫做HttpJspBase的類從而實現(xiàn)了一個通用化的JSP類,用戶在開發(fā)自己的JSP時,只需要從HttpJspBase繼承一個自己的類(如圖中Hello_jsp類),然后根據(jù)需要去實現(xiàn)相應的方法即可。 因此這也是為什么JSP的代碼中總是閃現(xiàn)Servlet代碼框架影子的原因,其實它們只是為實現(xiàn)同樣的功能而進行了不同封裝的組件而已,血脈里留著的是一樣的血。 “既生瑜何生亮?”呵呵,因為JSP確實比Servlet要更勝一籌,所謂“青出于藍勝于藍”,既然Sun公司要在Servlet基礎上推出JSP技術,那肯定是因為JSP有它更高明的地方。 使用Servlet產生動態(tài)網(wǎng)頁,需要在代碼中打印輸出很多HTML的標簽,此外,在Servlet中,我們不得不將靜態(tài)現(xiàn)實的內容和動態(tài)產生內容的代碼混合在一起。使用Servlet開發(fā)動態(tài)網(wǎng)頁,程序員和網(wǎng)頁編輯人員將無法一起工作,因為網(wǎng)頁編輯人員不了解Java語言,無法修改Servlet代碼,而Java程序員可能也不是很了解網(wǎng)頁編輯人員的意圖,以至于無法修改和實現(xiàn)網(wǎng)頁功能。為了解決這些問題,Sun公司就推出了JSP技術。
JSP是Servlet的擴展,在沒有JSP之前,就已經(jīng)出現(xiàn)了Servlet技術。Servlet是利用輸出流動態(tài)生成HTML頁面,包括每一個HTML標簽和每個在HTML頁面中出現(xiàn)的內容。 JSP通過在標準的HTML頁面中插入Java代碼,其靜態(tài)的部分無須Java程序控制,只有那些需要從數(shù)據(jù)庫讀取并根據(jù)程序動態(tài)生成信息時,才使用Java腳本控制。 事實上,JSP是Servlet的一種特殊形式,每個JSP頁面就是一個Servlet實例——JSP頁面由系統(tǒng)編譯成Servlet,Servlet再負責響應用戶請求。JSP其實也是Servlet的一種簡化,使用JSP時,其實還是使用Servlet,因為Web應用中的每個JSP頁面都會由Servlet容器生成對應的Servlet。對于Tomcat而言,JSP頁面生成的Servlet放在work路徑對應的Web應用下。 以apache-tomcat-7.0.37\webapps\myapp\index.jsp為例,
當啟動Tomcat之后,可以在Tomcat的apache-tomcat-7.0.37\work\Catalina\localhost\myapp\org\apache\jsp目錄下找到如下文件:indexd.java和index.class。這兩個文件都是Tomcat生成的,Tomcat根據(jù)JSP頁面生成對應Servlet的Java文件及class文件。 index.java JSP頁面中內置了幾個對象,如pageContext、application、config、page、session、out等_jspService()方法,這幾個內置對象就是在這里定義的。
根據(jù)上面的JSP頁面工作原理圖,可以得到如下結論: JSP文件必須在JSP服務器內運行。JSP文件必須生成Servlet才能執(zhí)行。每個JSP頁面的第一個訪問者速度很慢,因為必須等待JSP編譯成Servlet。JSP頁面的訪問者無須安裝任何客戶端,甚至不需要可以運行Java的運行環(huán)境,因為JSP頁面輸送到客戶端的是標準HTML頁面。index.jsp頁面中的每個字符都由index.java文件的輸出流生成. 所有基于Java的服務器端編程都是構建在Servlet之上的。在J2EE中Servlet已經(jīng)是一個標準的組件。 目前,Servlet引擎一般是第三方的插件,它通過一定的方法連接到Web服務器,Servlet引擎把它識別為Servlet請求的那些HTTP請求截獲下來處理,而其他的HTTP請求由Web服務器按照通常的方式來處理,Servlet引擎會裝載合適的Servlet到內存中,如果Servlet還沒有運行的話,會分配一個可以使用的線程來處理請求,再把Servlet的輸出返回到發(fā)出請求的Web客戶機。 Java Servlet和Java Applet正好是相對應的兩種程序類型,Applet運行在客戶端,在瀏覽器內執(zhí)行,而Servlet在服務器內部運行,通過客戶端提交的請求啟動運行。 同樣的Servlet完全可以在Apache,IIS等不同Web服務器上執(zhí)行,不管底層的操作系統(tǒng)是Windows,Solaris,Mac,Linux。 Java Servlet有著十分廣泛的應用。使用Servlet還可以實現(xiàn)大量的服務器端的管理維護功能,以及各種特殊的任務,比如,并發(fā)處理多個請求,轉送請求,代理等。 典型的Servlet運行環(huán)境有JSWDK,Tomcat,Resin等,。它們都自帶一個簡單的HTTP Server,只需簡單配置即可投入使用,你也可以把它們綁定到常用的Web服務器上,如Apache,IIS等,提供小規(guī)模的Web服務。還有一些商業(yè)的大中型的支持Servlet和JSP的Web服務器,如JRun,Web Sphere,Web Logic等等,配置比較復雜,并不適合初學者。但是功能較為強大,有條件的讀者可以一試。 Servlet與表單交互的方法 Servlet使用HttpServlet類中的方法與表單進行交互。在HttpServlet類中有幾個未完全實現(xiàn)的方法,你可以自己定義方法的內容,但是必須正確使用方法名稱以使HTTP Server把客戶請求正確的映射到相應的函數(shù)上。 doHeader 用于處理HEADER請求 doGet 用于處理GET請求,也可以自動的支持HEADER請求 doPost 用于處理POST請求 doPut 用于處理PUT請求 doDelete 用于處理DELETE請求
在使用這些方法時必須帶兩個參數(shù)。第一個包含來自客戶端的數(shù)據(jù)HttpServletRequest。第二個參數(shù)包含客戶端的相應HttpServletResponse。 一個HttpServletRequest對象提供請求HTTP頭部數(shù)據(jù),也允許獲取客戶端的數(shù)據(jù)。怎樣獲取這些數(shù)據(jù)取決于HTTP請求方法。不管何種HTTP方式,都可以用getParameterValues方法返回特定名稱的參數(shù)值。HttpServletRequest,HttpServletResponse接口分別繼承于ServletRequest和ServletResponse接口,getParameterValues和getWriter方法都是其祖先接口中的方法。 對于HTTP GET請求的方式,getQueryString方法將會返回一個可以用來解剖分析的參數(shù)值。 在進行HTTP網(wǎng)絡傳輸?shù)臅r候,統(tǒng)一采用的編碼方式是ISO-8859-1 字符編碼轉換常用的方法是 例:out.println(new String(new String("<td>你的姓名:</td>").getBytes(),"ISO-8859-1")); 用Servlet控制會話 會話狀態(tài)的維持是開發(fā)Web應用所必須面對的問題,有多種方法可以來解決這個問題,如使用Cookies,或直接把狀態(tài)信息加到URL中等,還有Servlet本身提供了一個HttpSession接口來支持會話狀態(tài)的維持 。 Session的發(fā)明是為了填補HTTP協(xié)議的局限。 從服務器這端來看,每一個請求都是獨立的,因此HTTP協(xié)議被認為是無狀態(tài)協(xié)議,當用戶在多個主頁間切換時,服務器無法知道他的身份。Session的出現(xiàn)就是為了彌補這個局限。利用Session,您就可以當一個用戶在多個主頁間切換的時候也能保存他的信息。這樣很多以前根本無法去做的事情就變得簡單多了。 Java Servlet定義了一個HttpSession接口,實現(xiàn)的Session的功能,在Servlet中使用Session的過程如下: 跟客戶端的Applet相似,Servlet也遵循嚴格的生命周期。在每個Servlet實例的生命中有三種類型的事件,這三種事件分別對應于由Servlet引擎所喚醒的三個方法: JSP一般的運行方式為:當服務器啟動后,當Web瀏覽器端發(fā)送過來一個頁面請求時,Web服務器先判斷是否是JSP頁面請求。如果該頁面只是一般的HTML/XML頁面請求,則直接將HTML/XML頁面代碼傳給Web瀏覽器端。如果請求的頁面是JSP頁面,則由JSP引擎檢查該JSP頁面,如果該頁面是第一次被請求、或不是第一次被請求但已被修改,則JSP引擎將此JSP頁面代碼轉換成Servlet代碼,然后JSP引擎調用服務器端的Java編譯器javac.exe對Servlet代碼進行編譯,把它變成字節(jié)碼(.class)文件,然后再調用JAVA虛擬機執(zhí)行該字節(jié)碼文件,然后將執(zhí)行結果傳給Web瀏覽器端。如果該JSP頁面不是第一次被請求,且沒有被修改過,則直接由JSP引擎調用JAVA虛擬機執(zhí)行已編譯過的字節(jié)碼.class文件,然后將結果傳送Web瀏覽器端。 采用JSP來表現(xiàn)頁面,采用Servlet來完成大量的處理,Servlet扮演一個控制者的角色,并負責響應客戶請求。Servlet創(chuàng)建JSP需要的Bean和對象,根據(jù)用戶的行為,決定將哪個JSP頁面發(fā)送給用戶。特別要注意的是,JSP頁面中沒有任何商業(yè)處理邏輯,它只是簡單的檢索Servlet先前創(chuàng)建的Beans或者對象,再將動態(tài)內容插入預定義的模板。 |
|