Servlet的概念.doc_第1頁
Servlet的概念.doc_第2頁
Servlet的概念.doc_第3頁
Servlet的概念.doc_第4頁
Servlet的概念.doc_第5頁
已閱讀5頁,還剩10頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Servlet的概念、配置與運(yùn)行 Java Servlet的概念Java Servlet是一個(gè)專門用于編寫網(wǎng)絡(luò)服務(wù)器應(yīng)用程序的Java組件。所有基于Java的服務(wù)器端編程都是構(gòu)建在Servlet之上的。在J2EE中Servlet已經(jīng)是一個(gè)標(biāo)準(zhǔn)的組件。了解Servlet在Java的軟件包中是怎樣的一個(gè)結(jié)構(gòu),這會有助于我們理解Servlet的概念。在J2EE中跟Servlet相關(guān)的一個(gè)包是javax.servlet,其中最基本的Servlet被聲明為一個(gè)接口javax.servlet: Interface Servlet,這是Servlet最高層次的一個(gè)抽象,它是和網(wǎng)絡(luò)協(xié)議無關(guān)的。同樣在javax.servlet中,實(shí)現(xiàn)了一個(gè)類 javax.servlet: class GenericServlet,這個(gè)類實(shí)現(xiàn)了Servlet接口,也是和協(xié)議無關(guān)的。而這個(gè)類是構(gòu)建其他和協(xié)議相關(guān)的Servlet子類型的通用的父類(至少HttpServlet是從它繼承而來的,從它的名字也能看出這一點(diǎn))。也就是說Servlet所適用的網(wǎng)絡(luò)協(xié)議可以是多種多樣的,比如HTTP,F(xiàn)TP,SMTP,TELNET等,但是就目前而言,只有HTTP服務(wù)已經(jīng)形成了標(biāo)準(zhǔn)的Java組件。對應(yīng)的軟件包有兩個(gè)javax.servlet.http和javax.servlet.jsp,分別對應(yīng)我們要講解的Servlet和JSP編程。我們通常所說的Servlet編程主要就是指針對HTTP的Servlet編程,用到的就是javax.servlet.http包中的類(典型的就是HttpServlet類),實(shí)際上Java Servlet編程的概念要更廣一些,在這里我們也就約定俗成的使用Servlet來指代HTTP Servlet的編程,這點(diǎn)你是需要了解的。由于JSP最終都是要經(jīng)過JSP引擎轉(zhuǎn)換成Servlet代碼的,而且Servlet編程和一般的Java編程是沒有大的區(qū)別的,只需要了解一定的規(guī)范即可,所以我們在這里先講解Servlet的編程,這樣對以后理解JSP是很大的有好處的,盡管在使用的時(shí)候可能JSP更為簡單一些。目前,Servlet引擎一般是第三方的插件,它通過一定的方法連接到Web服務(wù)器,Servlet引擎把它識別為Servlet請求的那些HTTP請求截獲下來處理,而其他的HTTP請求由Web服務(wù)器按照通常的方式來處理,Servlet引擎會裝載合適的Servlet到內(nèi)存中,如果Servlet還沒有運(yùn)行的話,會分配一個(gè)可以使用的線程來處理請求,再把Servlet的輸出返回到發(fā)出請求的Web客戶機(jī)。Java Servlet和Java Applet正好是相對應(yīng)的兩種程序類型,Applet運(yùn)行在客戶端,在瀏覽器內(nèi)執(zhí)行,而Servlet在服務(wù)器內(nèi)部運(yùn)行,通過客戶端提交的請求啟動運(yùn)行,你在學(xué)習(xí)過程可以作簡單的比較。使用過CGI的話一定知道CGI程序的作用,Servlet要實(shí)現(xiàn)的功能和CGI是一樣的,只是實(shí)現(xiàn)的時(shí)候更為方便,效率更高。Servlet的優(yōu)點(diǎn)和應(yīng)用范圍由于Servlet是用Java編寫的,所以它與生俱來就有跨平臺的特性,因此Servlet程序的設(shè)計(jì)完全和平臺是無關(guān)的,同樣的Servlet完全可以在Apache,IIS等不同Web服務(wù)器上執(zhí)行,不管底層的操作系統(tǒng)是Windows,Solaris,Mac,Linux還是其他的能支持Java的操作系統(tǒng)。Servlet是跟普通的Java程序一樣,是被編譯成字節(jié)碼后由JVM執(zhí)行的。相比傳統(tǒng)的CGI,盡管CGI是用本地代碼直接執(zhí)行的,但是由于每次客戶端發(fā)出請求,服務(wù)器必須啟動一個(gè)新的程序來處理請求,這就把高負(fù)載強(qiáng)加給了服務(wù)器資源,尤其如果CGI使用腳本語言編寫時(shí),如perl,服務(wù)器還必須啟動語言解釋程序,程序越多,占用的內(nèi)存就越多,消耗CPU也越多,嚴(yán)重影響系統(tǒng)性能。Servlet運(yùn)行于Servlet引擎管理的Java虛擬機(jī)中,被來自客戶機(jī)的請求所喚醒,與CGI不同的是,在虛擬機(jī)中只要裝載一個(gè)Servlet就能夠處理新的請求,每個(gè)新請求使用內(nèi)存中那個(gè)Servlet的相同副本,所以效率比CGI來得高。如果采用服務(wù)器端腳本,如ASP,PHP,語言解釋程序是內(nèi)置程序,因此可以加快服務(wù)器的運(yùn)行,但是效率還是比不上準(zhǔn)編譯的Servlet。實(shí)際的使用也已經(jīng)證明,Servlet是效率很高的服務(wù)器端程序,很適合用來開發(fā)Web服務(wù)器應(yīng)用程序。Java Servlet有著十分廣泛的應(yīng)用。不光能簡單的處理客戶端的請求,借助Java的強(qiáng)大的功能,使用Servlet還可以實(shí)現(xiàn)大量的服務(wù)器端的管理維護(hù)功能,以及各種特殊的任務(wù),比如,并發(fā)處理多個(gè)請求,轉(zhuǎn)送請求,代理等。Servlet的運(yùn)行環(huán)境為了運(yùn)行Servlet,首先當(dāng)然需要一個(gè)JVM來提供對Java的基本支持,一般需要安裝JRE(Java Runtime Environment)或JDK(Java Develop Kit,JRE是其一個(gè)子集)。其次我們需要Servlet API的支持,一般的Servlet引擎都自帶Servlet API,只要我們安裝Servlet引擎,或直接支持Servlet的Web服務(wù)器之后便會自動安裝上Servlet相關(guān)的程序包。典型的Servlet運(yùn)行環(huán)境有JSWDK,Tomcat,Resin等,這幾個(gè)都是免費(fèi)的軟件,適合用來學(xué)習(xí)Servlet和JSP。它們都自帶一個(gè)簡單的HTTP Server,只需簡單配置即可投入使用,你也可以把它們綁定到常用的Web服務(wù)器上,如Apache,IIS等,提供小規(guī)模的Web服務(wù)。還有一些商業(yè)的大中型的支持Servlet和JSP的Web服務(wù)器,如JRun,Web Sphere,Web Logic等等,配置比較復(fù)雜,但是功能較為強(qiáng)大,有條件的可以一試。后面會講解如何配置一簡單的支持Servlet和JSP的Web服務(wù)器。Servlet與CGI環(huán)境變量在使用CGI時(shí),最重要的內(nèi)容是CGI接口的環(huán)境變量。CGI規(guī)范列出了19個(gè)環(huán)境變量。盡管其他的環(huán)境變量,如HTTP_COOKIE(用于查詢站點(diǎn)信息的)不是該規(guī)范的組成部分,但也是經(jīng)常使用。由于Java運(yùn)行于JVM,不直接在服務(wù)器上運(yùn)行,所以不能直接訪問環(huán)境變量。由于CGI環(huán)境變量是Web服務(wù)器建立的,而且用戶能夠用其他的方法查詢變量值,所以Java不訪問環(huán)境變量沒有什么大問題。Java Servlet API定義幾種查詢在CGI環(huán)境變量中發(fā)現(xiàn)大多數(shù)信息的方法。有些信息是HTTP標(biāo)題的組成部分,而且采用HttpServletRequest類中的getHeader()方法能夠很容易的獲取。采用特殊的方法可以查詢其他的信息。Java唯一不可用的CGI環(huán)境變量是GATEWAY_INTERFACE。當(dāng)在CGI程序中使用時(shí),該變量包含CGI版本。在Java Servlet中這種變量信息是無關(guān)緊要的。以上的內(nèi)容是針對有CGI編程經(jīng)驗(yàn)的你的,通過對比能幫助更快的理解Servlet。Servlet的安全性Java Servlet能夠使用包括SSL在內(nèi)的安全協(xié)議。Servlet與Java內(nèi)在的安全措施緊密相連,如不能直接訪問內(nèi)存等。采用安全管理器,用戶能夠限定對其他資源的訪問,如文件、目錄和局域網(wǎng)。Java Servlet支持代碼符號,從而能夠更好的控制委托每個(gè)Servlet要執(zhí)行的程序。Java的安全機(jī)制本身是比較復(fù)雜的,在這里我們只能作簡單講解,具體的分析參看有關(guān)Java安全性的技術(shù)資料。Servlet的管理對于大多數(shù)用戶來說,Servlet比CGI程序和服務(wù)器腳本更容易管理。Servlet是以Java類的形式編譯的。Java采用能夠保存在Java Archive(.JAR)文件中的編制目錄樹內(nèi)的組件,提供一種管理類的方法,如Sun公司的Java Web服務(wù)器的Servlet管理平臺。有些服務(wù)器和第三方產(chǎn)品為管理Servlet提供圖形用戶界面。具體的Servlet的管理是比較復(fù)雜的一件事情,尤其是對于一個(gè)大系統(tǒng)而言。對于初學(xué)者只要能掌握基本的配置一個(gè)Servlet,使其能正常運(yùn)行的技能就可以了。更高級的技巧要在更多的實(shí)踐中才能真正掌握。Servlet的編譯Servlet的編譯和一般的Java程序是完全一樣的,在使用javac編譯的時(shí)候不需要任何特殊的參數(shù)。只要Servlet的編寫是正確的,編譯完后生成的Class文件就可以做為Servlet來運(yùn)行了。用Servlet Runner運(yùn)行Servlet在真正開始編寫Servlet之前,我們先介紹一個(gè)簡單的Servlet引擎-Resin。目前支持Servlet的Web服務(wù)器不下數(shù)十種,Resin是一個(gè)簡單易用的Servlet運(yùn)行器(Servlet Runner),很適合初學(xué)者。由于各個(gè)廠家的Servlet引擎各不相同,配置方法也是千差萬別,在這里不可能一概而論,但是Servlet的編寫方法卻是一樣的,所以你不必太在意服務(wù)器的配置方法,只要知道如何讓自己的Servlet正常運(yùn)行就可以了,把更多的注意力放在Servlet的編寫上。Resin自帶一個(gè)Servlet Runner和HTTP Server,因此要構(gòu)建一個(gè)簡單的Web環(huán)境,光有Resin已經(jīng)足夠了,不需要額外的支持軟件。Resin不需要安裝,解壓之后即可使用。Resin目錄下有幾個(gè)子目錄,bin目錄存放的是可執(zhí)行文件,要啟動HTTP Server和Servlet Runner只需要分別點(diǎn)擊其中的httpd.exe和srun.exe即可,啟動后會出現(xiàn)四個(gè)窗口,分別對應(yīng)HTTP Server的標(biāo)準(zhǔn)輸出,啟/停控制和Servlet Runner的標(biāo)準(zhǔn)輸出,啟/??刂啤onf目錄下存放的是Resin Servlet Runner的配置文件,這是配置整個(gè)Web環(huán)境的關(guān)鍵,包括Servlet的配置和后面要用到的JSP的配置。doc目錄是默認(rèn)的發(fā)布目錄,即Resin自帶的HTTP Server是以這個(gè)目錄為根目錄的。下面我們以一個(gè)最簡單的HelloWorld的例子,來講解如何配置Resin,使其能運(yùn)行Servlet程序,同時(shí)也做為Servlet編寫的入門。程序如下:/HelloServlet.javaimport java.io.*;import java.util.*;import javax.servlet.http.*;import javax.servlet.*;/導(dǎo)入必要的包public class HelloServlet extends HttpServlet /所有Servlet必須從HttpServlet派生public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException /doGet()是這個(gè)Servlet的核心,真正處理請求的地方res.setContentType(text/html); /設(shè)置相應(yīng)的類型為text/htmlPrintWriter pw = res.getWriter(); /從HttpServletResponse得到輸出流pw.println();pw.println();pw.println();pw.println();pw.println(Hello, world!);pw.println();pw.println();pw.println(Hello, world!);pw.println();/上面的語句都是向客戶端打印HTML文本pw.close(); /關(guān)閉HttpServletResponse,使Web服務(wù)器知道相應(yīng)結(jié)束public HelloServlet() /構(gòu)造函數(shù),可以不要這是最簡單的一個(gè)Servlet程序,整個(gè)類從HttpServlet派生,就跟Applet一樣,這個(gè)派生關(guān)系是必須的。這個(gè)Servlet必須實(shí)現(xiàn)doGet()方法(因?yàn)樗亲鳛殪o態(tài)頁面通過地址訪問的,這種方式在HTTP中稱為GET請求,在后面還會有更具體的講解),這是這個(gè)Servlet真正處理請求的地方,是整個(gè)Servlet的主體,就跟線程體的run()方法一樣。doGet()有兩個(gè)參數(shù)HttpServletRequest req和 HttpServletResponse res。HttpServletRequest包含了客戶請求的各種信息,HttpServletResponse則包裝了服務(wù)器響應(yīng),主要處理對客戶機(jī)的輸出。這個(gè)程序是很簡單的,如果對網(wǎng)絡(luò)編程和HTML有一些概念的話,很容易就應(yīng)該能理解。通過javac對以上程序進(jìn)行編譯,我們可以得到HelloServlet.class,下面我們就通過配置Resin來運(yùn)行這個(gè)Servlet。前面說過如果你沒有修改過Resin的配置文件的話,doc是Resin默認(rèn)的發(fā)布目錄。發(fā)布目錄下的WEB_INF/classes是Resin默認(rèn)的Classpath,你只要把自己的Servlet拷貝到該目錄下,Resin就能識別,當(dāng)然只要拷貝的有效的系統(tǒng)的或用戶的Classpath下,Resin都是能夠找到的。我們把HelloServlet.class拷貝到WEB_INF/classes目錄下。接下來就需要修改conf目錄下的resin.conf文件,來配置我們的Servlet。你可以使用任何一種自己所熟悉的文本編輯器來打開該配置文件。找到,在它和 之間任何地方添加以下的配置語句(可以參考已有的語句)這樣當(dāng)客戶端產(chǎn)生/Hello請求的時(shí)候,Resin就能把這個(gè)請求定向到HelloServlet上,該Servlet就能正常運(yùn)行了,我們也可以采用以下的配置語句這種情況下,沒有對Servlet的名字進(jìn)行映射,系統(tǒng)會默認(rèn)的使用servlet-name作為servlet-class進(jìn)行類的查找,所以servlet-name必須填寫正確的類名,而不能是隨意的名字。關(guān)于Resin更多的配置信息,有興趣的你可以參考Resin的幫助文檔,這里就不再贅述了。下面我們啟動Http Server和Servlet Runner(通過雙擊bin下的httpd.exe和srun.exe)。這樣我們就可以通過瀏覽器訪問這個(gè)Servlet了。打開瀏覽器,比如IE,在地址欄鍵入http:/localhost:8080/Hello,我們可以打開如下的一個(gè)網(wǎng)頁:通過查看源碼,我們可以得到如下的結(jié)果Hello, world!Hello, world!很顯然這些文本正是我們在Servlet中向客戶端所打印的信息,在Http頭部content=text/html也是我們在程序中所設(shè)置的。通過這樣一個(gè)簡單的HelloWorld的程序,你對Servlet的工作原理的基本配置方法應(yīng)該有了一個(gè)大概的了解。Servlet的應(yīng)用實(shí)例Servlet在編寫Web應(yīng)用方面的具體應(yīng)用。Servlet與表單交互的方法表單是HTML中使用最廣泛的傳遞信息的手段。搞清楚Servlet與表單的交互,就在客戶端與服務(wù)器之間架起了一座橋梁。Servlet使用HttpServlet類中的方法與表單進(jìn)行交互。在HttpServlet類中有幾個(gè)未完全實(shí)現(xiàn)的方法,你可以自己定義方法的內(nèi)容,但是必須正確使用方法名稱以使HTTP Server把客戶請求正確的映射到相應(yīng)的函數(shù)上。doHeader 用于處理HEADER請求doGet 用于處理GET請求,也可以自動的支持HEADER請求doPost 用于處理POST請求doPut 用于處理PUT請求doDelete 用于處理DELETE請求HttpServlet的Service方法,當(dāng)它接收到一個(gè)OPTIONS請求時(shí),它會自動調(diào)用doOptions方法,當(dāng)接收到一個(gè)TRACE請求時(shí)調(diào)用doTrace。DoOptions默認(rèn)執(zhí)行方式是自動決定什么樣的HTTP被選擇并返回哪個(gè)信息。在使用這些方法時(shí)必須帶兩個(gè)參數(shù)。第一個(gè)包含來自客戶端的數(shù)據(jù)HttpServletRequest。第二個(gè)參數(shù)包含客戶端的相應(yīng)HttpServletResponse。在我們的第一個(gè)例子中使用的是doGet方法,因?yàn)橥ㄟ^地址訪問的話,對應(yīng)的方式是GET。一個(gè)HttpServletRequest對象提供請求HTTP頭部數(shù)據(jù),也允許獲取客戶端的數(shù)據(jù)。怎樣獲取這些數(shù)據(jù)取決于HTTP請求方法。不管何種HTTP方式,都可以用getParameterValues方法返回特定名稱的參數(shù)值。 對于HTTP GET請求的方式,getQueryString方法將會返回一個(gè)可以用來解剖分析的參數(shù)值。對于用HTTP POST,PUT和DELETE請求的方式,HttpServletRequest有兩種方法可以選擇:如果是文本數(shù)據(jù),你能通過getReader的方法得到BufferedReader獲取數(shù)據(jù);如果是二進(jìn)制數(shù)據(jù),可以通過getInputStream方法得到ServletInputStream獲取數(shù)據(jù)。為了相應(yīng)客戶端,一個(gè)HttpServletResponse對象提供返回?cái)?shù)據(jù)給用戶的兩個(gè)方法:一種是用getWriter方法得到一個(gè)PrintWriter,用于返回文本數(shù)據(jù);另一種方法是用getOutputStream方法得到ServletOutputStream,用于返回二進(jìn)制數(shù)據(jù)。在使用Writer或OutputStream之前應(yīng)先設(shè)置頭部(HttpServletResponse中有相應(yīng)的方法),然后用Writer或OutputStream將相應(yīng)的主體部分發(fā)給用戶。完成后要關(guān)閉Writer或OutputStream以便讓服務(wù)器知道相應(yīng)已經(jīng)結(jié)束。下面我們舉一個(gè)使用HttpServletRequest和HttpServletResponse得到并打印客戶端信息的例子:/RequestInfo.javaimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class RequestInfo extends HttpServlet public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException /處理GET請求的方法response.setContentType(text/html); /先設(shè)置Header,在這里只設(shè)置ContentType一項(xiàng)PrintWriter out = response.getWriter(); /得到文本輸出Writer/下面打印相關(guān)的HTMLout.println();out.println();out.println(Request Information Example);out.println();out.println();out.println(Request Information Example);out.println(Request URI: + request.getRequestURI()+); /打印請求的路徑out.println(Protocol: + request.getProtocol()+); /打印協(xié)議名稱out.println(PathInfo: + request.getPathInfo()+); /打印額外的路徑信息out.println(Remote Address: + request.getRemoteAddr(); /打印客戶機(jī)的地址,如果沒有打印IP地址out.println();out.println();out.close(); /關(guān)閉Writer public void doPost(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException/如果是POST請求類型,同樣調(diào)用GET類型的響應(yīng)函數(shù)doGet(request, response);用我們在前面介紹的方法在Resin中配置使其運(yùn)行,我們得到的結(jié)果如下:這樣的一個(gè)例子很好的說明了所謂的動態(tài)網(wǎng)頁和靜態(tài)網(wǎng)頁的區(qū)別,就上面這個(gè)例子而言,每個(gè)客戶看到的內(nèi)容是不一樣的,而靜態(tài)網(wǎng)頁則對每一個(gè)客戶而言都是一成不變的。Servlet與表單交互的例子上面我們介紹了Servlet如何與表單進(jìn)行交互,并提供了一個(gè)從HTTP請求頭部得到客戶端信息的例子,下面我們給出一個(gè)Servlet與HTTP提交的表單進(jìn)行交互的例子,通過這個(gè)例子你應(yīng)該能對整個(gè)客戶端和服務(wù)器端交互的過程有一個(gè)整體的了解。這個(gè)例子分成兩個(gè)文件,一個(gè)是靜態(tài)的HTML文件,提供一個(gè)表單,并設(shè)置提交按鈕,表單被提交后,服務(wù)器會把它定向到另一個(gè)文件,也就是我們的Servlet,由它讀取表單并打印到客戶端。1. 靜態(tài)HTML文本:ourform.htmlOur FormOur Form姓名:性別:男女在IE下顯示效果如圖所示:不熟悉HTML的你可以參考有關(guān)HTML的書籍,尤其要注意的form的兩個(gè)屬性method和action2. FormDemo.java/FormDemo.javaimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class FormDemo extends HttpServlet public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException /處理GET請求的方法response.setContentType(text/html); /先設(shè)置Header,在這里只設(shè)置ContentType一項(xiàng)PrintWriter out = response.getWriter(); /得到文本輸出WriterString name = request.getParameter(Name); /得到表單值NameString sex = request.getParameter(Sex); /得到表單值Sexname = new String(name.getBytes(),ISO-8859-1); /轉(zhuǎn)換到正確的編碼/打印得到的表單值out.println();out.println();out.println();out.println(Your Info);out.println();out.println();out.println(Data You Posted);out.println();out.println();out.println(new String(new String(你的姓名:).getBytes(),ISO-8859-1);out.println(+name+);out.println();out.println();out.println(new String(new String(你的性別:).getBytes(),ISO-8859-1);out.print();if(sex.equals(1) out.println(new String(new String(男).getBytes(),ISO-8859-1);else out.println(new String(new String(女).getBytes(),ISO-8859-1);out.println();out.println();out.println();out.println();out.close(); /關(guān)閉Writer這個(gè)Servlet也是比較簡單的,首先從提交的表單中得到需要的兩個(gè)值,然后用HTML向客戶端打印這些信息。值得注意的是,在這個(gè)例子中,所有出現(xiàn)打印中文的地方,我們都使用了字符編碼的轉(zhuǎn)換來正確打印中文。前面的例子我們都沒有涉及中文,在這里我們有必要提一下Servlet的中文問題。我們知道在同一臺機(jī)器上,所有的編碼方式都是一樣的,一般中文平臺是gb2312,英文平臺是ISO-8859-1,但是網(wǎng)絡(luò)上的兩臺機(jī)器并不能保證他們的編碼方式都是一樣的,這時(shí)候就有可能出現(xiàn)亂碼的問題。在進(jìn)行HTTP網(wǎng)絡(luò)傳輸?shù)臅r(shí)候,統(tǒng)一采用的編碼方式是ISO-8859-1,這時(shí)候如果還是按照本地編碼來傳輸就會出現(xiàn)問題,這也是Servlet在實(shí)現(xiàn)網(wǎng)絡(luò)傳輸?shù)臅r(shí)候一個(gè)不完美的地方,它不會自動進(jìn)行本地編碼到ISO-8859-1的轉(zhuǎn)換,所以直接打印的話就會出現(xiàn)亂碼。原理上講任何出現(xiàn)打印字符串的地方,都是需要進(jìn)行編碼轉(zhuǎn)換的,但是西文字符在不同字符集下對應(yīng)相同的編碼,以在打印西文字符的時(shí)候就不需要轉(zhuǎn)換了。在Servlet后繼的規(guī)范中可能會改變這種麻煩的狀況。不同的是,從網(wǎng)絡(luò)提交的表單數(shù)據(jù),Servlet是自動把它轉(zhuǎn)換成本地編碼的,所以程序中得到的name字符串變量是gb2312編碼的,同樣需要進(jìn)行轉(zhuǎn)換后才能在客戶端正確打印。字符編碼轉(zhuǎn)換常用的方法是String native_encoded = 中文字符串; /本地編碼的字符串Byte byte_array = native_encoded.getBytes(); /得到本地編碼的字節(jié)數(shù)組String net_encoded = new String(native_encoded, ISO-8859-1); /生成ISO-8859-1編碼的字符串這樣得到的net_encoded字符串就可以用來向客戶端打印而不出錯(cuò)了。還有一點(diǎn)要注意的是,為了在客戶端正常顯示中文,必須在HTML頭部設(shè)置charset=gb2312。當(dāng)我們按下提交按鈕后,我們得到的結(jié)果如下:如果我們把ourform.html中的method由GET改成POST,會有什么樣的結(jié)果呢?由于我們沒有重寫doPost方法,所以在Resin下,我們得到如下的結(jié)果:有興趣的你可以修改FormDemo類來響應(yīng)POST方法。通過以上的幾個(gè)例子,你對Servlet如何響應(yīng)HTTP請求,并從提交的表單中獲取數(shù)據(jù)應(yīng)該有了一個(gè)大概的了解,但是要構(gòu)建Web應(yīng)用程序,光有這幾點(diǎn)是不夠的,下面我們要講解的Servlet的會話和生命周期對于構(gòu)建Web應(yīng)用是及其重要的兩個(gè)特性。用Servlet控制會話會話狀態(tài)的維持是開發(fā)Web應(yīng)用所必須面對的問題,有多種方法可以來解決這個(gè)問題,如使用Cookies,hidden類型的表單域,或直接把狀態(tài)信息加到URL中等,還有Servlet本身提供了一個(gè)HttpSession接口來支持會話狀態(tài)的維持,在這里我們主要介紹基于這個(gè)接口的會話狀態(tài)的管理。Session的發(fā)明是為了填補(bǔ)HTTP協(xié)議的局限。請注意HTTP協(xié)議是如何工作的-用戶發(fā)出請求,服務(wù)器作出響應(yīng),這種用戶端和服務(wù)器端的聯(lián)系就是離散的,非連續(xù)的。HTTP協(xié)議不能提供允許服務(wù)器跟蹤用戶請求的功能。在服務(wù)器端完成響應(yīng)用戶的請求之后,服務(wù)器不能繼續(xù)與該瀏覽器繼續(xù)保持連接。從服務(wù)器這端來看,每一個(gè)請求都是獨(dú)立的,因此HTTP協(xié)議被認(rèn)為是無狀態(tài)協(xié)議,當(dāng)用戶在多個(gè)主頁間切換時(shí),服務(wù)器無法知道他的身份。Session的出現(xiàn)就是為了彌補(bǔ)這個(gè)局限。利用Session,您就可以當(dāng)一個(gè)用戶在多個(gè)主頁間切換的時(shí)候也能保存他的信息。這樣很多以前根本無法去做的事情就變得簡單多了。在訪問者從到達(dá)某個(gè)特定的主頁到離開為止的那段時(shí)間,每個(gè)訪問者都會單獨(dú)獲得一個(gè)Session。Java Servlet定義了一個(gè)HttpSession接口,實(shí)現(xiàn)的Session的功能,在Servlet中使用Session的過程如下:(1) 使用HttpServletRequest的getSession方法得到當(dāng)前存在的session,如果當(dāng)前沒有定義session,則創(chuàng)建一個(gè)新的session,還可以使用方法getSession(true)(2) 寫session變量??梢允褂梅椒℉ttpSession.setAttribute(name,value)來向Session中存儲一個(gè)信息。也可以使用HttpSession.putValue(name,value),但這個(gè)方法已經(jīng)過時(shí)了。(3) 讀Session變量??梢允褂梅椒℉ttpSession.getAttribute(name)來讀取Session中的一個(gè)變量值,如果name是一個(gè)沒有定義的變量,那么返回的是null。需要注意的是,從getAttribute讀出的變量類型是Object,必須使用強(qiáng)制類型轉(zhuǎn)換,比如:String uid = (String) session.getAttribute(uid);也可以使用HttpSession.getValue(name),但是這個(gè)方法也已經(jīng)過時(shí)了。(4) 關(guān)閉session,當(dāng)時(shí)用完session后,可以使用session.invalidate()方法關(guān)閉session。但是這并不是嚴(yán)格要求的。因?yàn)?,Servlet引擎在一段時(shí)間之后,自動關(guān)閉seesion。下面舉一個(gè)簡單的例子說明session的使用/ SessionExample.javaimport java.io.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;/導(dǎo)入必要的軟件包public class SessionExample extends HttpServlet public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException /實(shí)現(xiàn)doGet方法response.setContentType(text/html); /設(shè)置HTTP頭PrintWriter out = response.getWriter(); /得到輸出WriterHttpSession session = request.getSession(true); /得到session對象/打印HTML標(biāo)記out.println();out.println();out.println();out.println();out.println();Date created = new Date(session.getCreationTime(); /得到session對象創(chuàng)建的時(shí)間Date accessed = new Date(session.getLastAccessedTime();/得到最后訪問該session對象的時(shí)間out.println(ID + session.getId()+); /得到該session的id,并打印out.println(Created: + created+);/打印session創(chuàng)建時(shí)間out.println(Last Accessed: + accessed+); /打印最后訪問時(shí)間session.setAttribute(UID,12345678); /在session中添加變量UID=12345678session.setAttribute(Name,Tom); /在session中添加變量Name=TomEnumeration e = session.getAttributeNames(); /得到session中變量名的枚舉對象while (e.hasMoreElements() /遍歷每一個(gè)變量String name = (String)e.nextElement(); /首先得到名字String value = session.getAttribute(name).toString(); /由名字從session中得到值out.println(name + = + value+); /打印out.println(); /打印HTML標(biāo)記out.println();該Servlet運(yùn)行的結(jié)果是:有了Session對象,Web應(yīng)用程序就可以在服務(wù)器端保存客戶的狀態(tài),這對構(gòu)建Web應(yīng)用的重要性你在以后的實(shí)踐中會逐步有所體會。正像前面提到的,Session只是一個(gè)概念,可以有多種實(shí)現(xiàn)方法,在這里我們就不過多的介紹了。因?yàn)镾ervlet本身就是實(shí)用性很強(qiáng)的內(nèi)容,各種各樣的技巧,實(shí)現(xiàn)方案,不勝枚舉。而且很多相關(guān)內(nèi)容也不只是Servlet的專利,在這里只能做簡單的介紹,使你對Servlet有一個(gè)概念上的認(rèn)識。有興趣的話可以參考相關(guān)資料。Servlet的生命周期跟客戶端的Applet相似,Servlet(這里Servlet的概念又回到了最原始的含義)也遵循嚴(yán)格的生命周期。在每個(gè)Servlet實(shí)例的生命中有三種類型的事件,這三種事件分別對應(yīng)于由Servlet引擎所喚醒的三個(gè)方法:1init()。當(dāng)Servlet第一次被裝載時(shí)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論