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

下載本文檔

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

文檔簡(jiǎn)介

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

溫馨提示

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

評(píng)論

0/150

提交評(píng)論