版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第7章Servlet編程7.1從CGI到Servlet7.2Servlet生命周期7.3Servlet的開發(fā)實(shí)例
【學(xué)習(xí)提示】Servlet的本質(zhì)就是一個(gè)Java類,目的是為客戶服務(wù)。它的任務(wù)是獲取一個(gè)客戶的請求,對請求進(jìn)行相應(yīng)處理后,再發(fā)回一個(gè)響應(yīng)。本章重點(diǎn)講解Servlet如何獲取和使用客戶端請求,怎樣發(fā)送響應(yīng)或者不發(fā)送響應(yīng)直接進(jìn)行重定向讓瀏覽器完成工作,以及Servlet的整個(gè)開發(fā)、配置和使用流程。學(xué)習(xí)Servlet是掌握J(rèn)SP的基礎(chǔ)和前提,因?yàn)镴SP在首次運(yùn)行時(shí)都會被Tomcat容器自動轉(zhuǎn)換為Servlet,再次運(yùn)行時(shí)由Tomcat直接調(diào)用該Servlet。
7.1.1CGI簡介
與瀏覽器端技術(shù)從靜態(tài)向動態(tài)的演進(jìn)過程類似,Web服務(wù)端的技術(shù)也是由靜態(tài)向動態(tài)逐漸發(fā)展并完善起來的。早期的Web服務(wù)器只能簡單地響應(yīng)瀏覽器發(fā)來的HTTP請求,并將存儲在服務(wù)器上的HTML文件返回給瀏覽器,直到通用網(wǎng)關(guān)接口(CommonGatewayInterface,CGI)技術(shù)的產(chǎn)生才使得Web服務(wù)器可根據(jù)運(yùn)行時(shí)的具體情況(如數(shù)據(jù)庫的實(shí)時(shí)數(shù)據(jù))動態(tài)生成HTML頁面。7.1從CGI到ServletCGI是外部應(yīng)用程序與Web服務(wù)器交互的一個(gè)標(biāo)準(zhǔn)接口。1993年,CGI1.0的標(biāo)準(zhǔn)草案由美國國家超級計(jì)算機(jī)應(yīng)用中心(NationalCenterforSupercomputingApplications,NCSA)提出,并于1995年制定了CGI1.1標(biāo)準(zhǔn)。把遵循CGI標(biāo)準(zhǔn)編寫的服務(wù)器端的可執(zhí)行程序稱為CGI程序。隨著CGI技術(shù)的普及,聊天室、論壇、電子商務(wù)、搜索引擎等各式各樣的Web應(yīng)用蓬勃興起,使得互聯(lián)網(wǎng)真正成為信息檢索、信息交換和信息處理的超級工具。
CGI技術(shù)允許服務(wù)端的應(yīng)用程序根據(jù)客戶端的請求,動態(tài)生成HTML頁面,這使客戶端和服務(wù)器端的動態(tài)信息交換成為了可能。絕大多數(shù)的CGI程序被用來解釋處理用戶在HTML文件的表單中所輸入的信息,然后在服務(wù)器進(jìn)行相應(yīng)的處理并將結(jié)果信息動態(tài)編寫為HTML文件反饋給瀏覽器。
CGI程序大多是編譯后的可執(zhí)行程序,其編程語言可以是C、C++、Pascal或Perl等程序設(shè)計(jì)語言。其中,Perl的跨操作系統(tǒng)、易于修改等特性使它成為CGI的主要編程語言。目前幾乎所有的Web服務(wù)器都支持CGI。CGI程序的工作過程如圖7-1所示,具體流程如下:
(1)用戶指示瀏覽器訪問一個(gè)URL;
(2)瀏覽器通過HTML表單或超鏈接請求指向一個(gè)CGI程序的URL;
(3)
Web服務(wù)器收到請求,并在服務(wù)器端執(zhí)行所指定的CGI程序;
(4)
CGI程序根據(jù)參數(shù)執(zhí)行所需要的操作;
(5)
CGI程序把結(jié)果格式化為HTML網(wǎng)頁;
(6)
Web服務(wù)器把結(jié)果返回到瀏覽器中。
圖7-1CGI的基本操作
雖然CGI技術(shù)為Web服務(wù)器端帶來了動態(tài)生成HTML文檔的能力,但CGI的缺點(diǎn)也是較為明顯的:CGI的應(yīng)用程序一般都是一個(gè)獨(dú)立的可執(zhí)行程序,每一個(gè)用戶的請求都會激活一個(gè)CGI進(jìn)程。當(dāng)用戶請求數(shù)量非常大時(shí),大量的CGI程序就會吞噬系統(tǒng)資源,造成Web服務(wù)器運(yùn)行效率低下。另外,在CGI程序設(shè)計(jì)過程中,代碼編寫方式(在語言中不斷嵌入HTML文檔片段)、調(diào)試等環(huán)節(jié)非常繁瑣,開發(fā)效率不高。7.1.2ISAPI與NSAPI簡介
ISAPI(InternetServerAPI)與NSAPI(NetscapeServerAPI)是分別由Microsoft公司和Netscape公司定義的Web服務(wù)器應(yīng)用程序編程接口。雖然兩種技術(shù)所支持的Web服務(wù)器產(chǎn)品不同,但它們的定位和原理相似,以下主要討論ISAPI。
ISAPI與CGI的工作原理相似,都是通過交互式網(wǎng)頁獲取用戶輸入的信息,然后交服務(wù)器后臺處理。ISAPI與CGI最大的區(qū)別在于:在ISAPI下建立的應(yīng)用程序都是以動態(tài)鏈接庫(DLL)的形式存在的。基于ISAPI進(jìn)程需要的系統(tǒng)資源也較CGI少,因此ISAPI的運(yùn)行效率要顯著高于CGI程序。可以使用ISAPI篩選器來過濾瀏覽器端與服務(wù)器端之間來回傳送的數(shù)據(jù),如登錄數(shù)據(jù)或URL請求等。當(dāng)發(fā)生選定事件時(shí)相應(yīng)的篩選器就被調(diào)用,通過這種機(jī)制,網(wǎng)站可以監(jiān)視或更改瀏覽器端與服務(wù)器端之間傳送的數(shù)據(jù)。ISAPI篩選器常用來實(shí)現(xiàn)網(wǎng)站的權(quán)限控制、自定義加密、自定義壓縮和用戶訪問日志等功能。
能夠用來開發(fā)ISAPI程序的語言有VisualC++、VisualBasic、BorlandC++
和Delphi等,支持ISAPI程序運(yùn)行的Web服務(wù)器主要是Microsoft公司的IIS(InternetInformationServices)服務(wù)器。支持NSAPI程序運(yùn)行的Web服務(wù)器主要是Netscape公司的EnterpriseServer和Sun公司的JavaWebServer等產(chǎn)品。7.1.3Servlet簡介
與CGI程序類似,Servlet程序也是一種Web服務(wù)器端的應(yīng)用程序,可以根據(jù)用戶的需求動態(tài)生成Web頁面。Servlet程序由Java語言開發(fā),由Web服務(wù)器進(jìn)行加載,并在服務(wù)器端的Java虛擬機(jī)中運(yùn)行。
在大量用戶訪問的Web服務(wù)器上,Servlet的優(yōu)點(diǎn)表現(xiàn)在它的執(zhí)行速度快于CGI程序。每個(gè)用戶請求被激活成一個(gè)線程而非單獨(dú)的進(jìn)程,這意味著服務(wù)器端處理請求的系統(tǒng)開銷將明顯降低。這一點(diǎn)非常類似于ISAPI的運(yùn)行機(jī)理。
Servlet的基本結(jié)構(gòu)代碼如下:
importjava.io.*;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/*上面是servlet必須引入的類*/
publicclasstestextendsHttpServlet{//Servlet繼承父類HttpServlet
publictest(){//該對象的構(gòu)造方法
super();
}
publicvoiddestroy(){//銷毀該Servlet
super.destroy();//繼承父類的destroy()方法
}
publicvoiddoDelete(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{/*當(dāng)收到一個(gè)HTTP的delete請求時(shí)調(diào)用該方法,參變量request表示從客戶端到服務(wù)器端發(fā)送的請求,參變量response表示從服務(wù)器端到客戶端發(fā)送的響應(yīng),當(dāng)發(fā)生錯(cuò)誤時(shí)拋出ServletException和IOException異常*/
}
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
/*當(dāng)客戶端發(fā)送請求的方式為get時(shí)調(diào)用該方法,即通過瀏覽器直接請求該Servlet或者表單中method的值為get*/
response.setContentType("text/html");
PrintWriterout=response.getWriter();
out.println("<!DOCTYPEHTMLPUBLIC\"-//W3C//DTDHTML4.01Transitional//EN\">");
out.println("<HTML>");
out.println("<HEAD><TITLE>AServlet</TITLE></HEAD>");
out.println("<BODY>");
out.print("Thisis");
out.print(this.getClass());
out.println(",usingtheGETmethod");
out.println("</BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
/*當(dāng)客戶端發(fā)送請求的方式為post時(shí)調(diào)用該方法,即表單的method值為post*/
doGet(request,response);//直接調(diào)用doGet方法
}
publicvoiddoPut(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//當(dāng)接收到put請求時(shí)調(diào)用該方法
//Putyourcodehere
}
publicStringgetServletInfo(){//返回Servlet的相關(guān)信息,例如作者等
return"ThisismydefaultservletcreatedbyEclipse";
}
publicvoidinit()throwsServletException{//Servlet的初始化方法
//Putyourcodehere
}
}
在上述Servlet的所有方法中doGet()和doPost()方法體現(xiàn)了Servlet的主要功能,要根據(jù)具體的請求方式來確定寫doGet()方法還是doPost()方法。
前面章節(jié)中介紹了同樣是基于Java的網(wǎng)站設(shè)計(jì)技術(shù)Applet。與Servlet比較,兩者具有的相似之處包括:
(1)它們都不是獨(dú)立的應(yīng)用程序,沒有main()方法;
(2)它們都不是由用戶或程序員調(diào)用,而是由另外一個(gè)應(yīng)用程序(瀏覽器或服務(wù)器)
調(diào)用;
(3)它們都包含init()和destroy()方法,用來定義生命周期。但Applet與Servlet又具有很大不同:Applet具有圖形界面,在客戶端運(yùn)行;而Servlet則沒有圖形界面,在服務(wù)器端運(yùn)行。
最早支持Servlet技術(shù)的是JavaWebServer。此后,基于Java的穩(wěn)定性和跨平臺性等優(yōu)點(diǎn),大量的Web服務(wù)器開始支持標(biāo)準(zhǔn)的ServletAPI。
Servlet容器(即Tomcat)會全盤控制Servlet的一生,它會創(chuàng)建請求和響應(yīng)對象,為Servlet創(chuàng)建一個(gè)新線程或分配一個(gè)線程,同時(shí)調(diào)用Servlet的service()方法,傳遞請求和響應(yīng)對象的引用作為參數(shù)。容器還會對創(chuàng)建的Servlet實(shí)例進(jìn)行適當(dāng)?shù)墓芾?,服?wù)器內(nèi)存不夠時(shí),要撤銷較老的未用實(shí)例。因此,每個(gè)Servlet都有一個(gè)生命期。7.2Servlet生命周期容器創(chuàng)建一個(gè)實(shí)例時(shí),生命期開始;容器把該實(shí)例從服務(wù)中刪除并撤銷時(shí),生命期終止。如圖7-2所示的Servlet生命周期說明了初始化和撤銷等重要事件何時(shí)發(fā)生。
圖7-2Servlet的生命周期上述生命周期可以概括為以下四個(gè)步驟:
(1)第一次訪問一個(gè)Servlet時(shí),Web容器會加載類并創(chuàng)建它的一個(gè)實(shí)例。所謂的Web容器就是為Servlet提供運(yùn)行環(huán)境,Servlet的運(yùn)行必須依賴于Web容器,不能獨(dú)立于容器運(yùn)行。前面提到的Tomcat即為Web容器。當(dāng)容器收到第一個(gè)請求時(shí),會創(chuàng)建一個(gè)Servlet實(shí)例,即運(yùn)行Servlet類的無參數(shù)構(gòu)造函數(shù)。
(2)如果需要,要初始化這個(gè)實(shí)例。用構(gòu)造函數(shù)創(chuàng)建的實(shí)例只是一個(gè)普通的對象,而不是一個(gè)Servlet。要想成為一個(gè)Servlet,必須進(jìn)行初始化,使其具備一些“Servlet特性”,能為客戶請求提供服務(wù)。初始化工作由容器即Tomcat完成。對于創(chuàng)建的每個(gè)Servlet實(shí)例,初始化工作應(yīng)當(dāng)只完成一次,而且要通過調(diào)用該Servlet的init()方法完成。服務(wù)器一旦初始化了一個(gè)Servlet,這個(gè)Servlet就處于準(zhǔn)備狀態(tài),可以在任何時(shí)刻調(diào)用此Servlet來處理到來的請求。
(3)維護(hù)這個(gè)實(shí)例,處理到來的請求。每個(gè)客戶請求到來時(shí),容器會開啟一個(gè)新線程,或者從線程池分配一個(gè)線程,并調(diào)用Servlet的service()方法。該方法根據(jù)請求的HTTP方法(GET、POST等)來調(diào)用doGet()或doPost()方法。一般在doGet()或doPost()中寫客戶自己的代碼。客戶的Web應(yīng)用想要做什么,就由這個(gè)方法負(fù)責(zé)。
容器可以在Servlet的這個(gè)階段對該Servlet調(diào)用多次service()方法,通過運(yùn)行多個(gè)線程來處理對一個(gè)Servlet的多個(gè)請求,如圖7-3所示。對應(yīng)每個(gè)客戶請求,會生成一對新的請求和響應(yīng)對象。
圖7-3Servlet線程分配
(4)如果需要為新的Servlet實(shí)例讓出空間,則刪除Servlet實(shí)例。Servlet的生命周期中,大多數(shù)時(shí)間一般都是在為到來的請求提供服務(wù)。如果一個(gè)服務(wù)器負(fù)載過重,可能會出現(xiàn)這樣一些情況,即需要加載新的Servlet,但是沒有足夠的內(nèi)存資源來保證安全的加載。在這些情況下,容器中的資源管理邏輯就可能會從服務(wù)中選擇刪除一個(gè)Servlet實(shí)例。在所有情況下,這個(gè)資源管理邏輯都會選擇刪除最不可能用到的Servlet實(shí)例。在刪除Servlet之前,Servlet規(guī)范要求容器調(diào)用該Servlet的destroy()方法,然后進(jìn)行垃圾收集。
下面通過一個(gè)簡單Servlet開發(fā)、配置與調(diào)用的實(shí)例展示Servlet的具體使用方法及其生命周期。7.3Servlet的開發(fā)實(shí)例7.3.1編寫Servlet代碼
選擇合適的編輯工具,編寫類名為HelloWorld的Servlet源文件,具體代碼如下:
HelloWorld.java
importjava.io.*;
importjavax.servlet.http.*;
importjavax.servlet.*;
/*上面是Servlet必須引入的3個(gè)類*/
publicclassHelloWorldextendsHttpServlet{
publicHelloWorld(){//構(gòu)造函數(shù)
super();
}
/*下面的doGet()方法處理以Get方式提交過來的數(shù)據(jù)*/
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException,ServletException
{
response.setContentType("text/html");
PrintWriterout=response.getWriter();
//下面的代碼實(shí)現(xiàn)向客戶端瀏覽器輸入內(nèi)容
out.println("<html>");
out.println("<head>");
out.println("<title>HelloWorld</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>HelloWorld!</h1>");
out.println("</body>");
out.println("</html>");
}
//下面的doPost()方法處理以Post方式提交過來的數(shù)據(jù)
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
doGet(request,response);
}
publicvoidinit()throwsServletException{//該Servlet裝載到容器后將自動執(zhí)行的初始方法
//放置初始化代碼
}
publicvoiddestroy(){//銷毀時(shí)調(diào)用的方法
super.destroy();
}
}在編寫Servlet時(shí),重點(diǎn)要根據(jù)請求數(shù)據(jù)的提交方式重寫doGet或doPost方法,當(dāng)需要處理表單提交的數(shù)據(jù)時(shí),可以依據(jù)form屬性method的取值來確定是重寫doGet還是doPost方法。客戶端提交的數(shù)據(jù)均封裝在request對象中,通過調(diào)用該對象的相應(yīng)方法可以獲取提交的參數(shù)值。對request對象的詳細(xì)講解參見9.2節(jié)。7.3.2編譯和部署Servlet
1.編譯Servlet
如果采用MyEclipse編寫Servlet代碼,點(diǎn)擊保存后,會自動生成對應(yīng)的字節(jié)碼文件(即
.class文件)。如果沒有采用開發(fā)工具,則可以直接在命令行窗口中運(yùn)行javac命令將HelloWorld.java文件編譯成字節(jié)碼文件,如下圖7-4所示。
圖7-4Servlet的class文件
2.部署Servlet
所謂部署Servlet就是把
.class文件放到其所屬Web服務(wù)應(yīng)用文件下的/WEB-INF/
classes/目錄下。如果用package語句指明了Servlet類所在的包,則要在classes目錄下按照包結(jié)構(gòu)創(chuàng)建子文件夾。
本節(jié)創(chuàng)建的HelloWorldServlet用于名為Chapter7的Web應(yīng)用。它在Tomcat容器中的位置如下圖7-5所示。
圖7-5HelloWorld.class文件的部署7.3.3配置Servlet
在Web應(yīng)用的web.xml文件中配置Servlet(HelloWorld.class)的信息,包括Servlet定義邏輯名和訪問路徑(相對URL地址),具體代碼如下:
web.xml
<web-appversion="2.5"xmlns="/xml/ns/javaee"
xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="http:
///xml/ns/javaee/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>MyServlet</servlet-name>
<!--標(biāo)簽servlet-name用于給servlet起一個(gè)名字,例如MyServlet,這是一個(gè)虛構(gòu)的名字,只能在Web應(yīng)用的部署描述文檔(即Web.xml)的其他部分使用-->
<servlet-class>HelloWorld</servlet-class>
<!--標(biāo)簽servlet-class用于指定名為MyServlet的Servlet對應(yīng)的類文件的完全限定名-->
</servlet>
<servlet-mapping>
<!--標(biāo)簽servlet-mapping用于規(guī)定前面起好名字的Servlet的訪問路徑-->
<servlet-name>MyServlet</servlet-name>
<!--直接使用前面創(chuàng)建的Servlet名表示要為哪個(gè)Servlet規(guī)定訪問路徑-->
<url-pattern>/Servlet-example</url-pattern>
<!--標(biāo)簽url-pattern的值“/Servlet-example”表示調(diào)用MyServlet的URL路徑,以Web應(yīng)用的路徑為根目錄,譬如在本書中該Servlet絕對調(diào)用路徑為:http://localhost:8080/Chapter7/Servlet-example-->
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
web.xml的具體結(jié)構(gòu)信息參見6.4.2節(jié)。從上述實(shí)例可以看出在web.xml文檔中必須要為Servlet配置兩個(gè)信息:一個(gè)是給Servlet起名字并指定其對應(yīng)的class文件,另一個(gè)是規(guī)定該Servlet的相對訪問路徑并建立其訪問路徑之間的映射關(guān)系。7.3.4測試Servlet
部署包含該Servlet的Web應(yīng)用(本書中為Chpater7),啟動瀏覽器,訪問http://localhost:
8080/Chapter7/Servlet-example,運(yùn)行名為MyServlet的Servlet,顯示結(jié)果如圖7-6所示。
圖7-6MyServlet的運(yùn)行結(jié)果7.3.5Servlet初始化參數(shù)
對于經(jīng)常發(fā)生變化的值不適宜在Servlet類中硬編碼寫入,而可以將其作為Servlet的初始化參數(shù)寫到web.xml文檔中。例如,在Servlet中要打印輸出email地址:
out.println("lianxi@");
如果email有變化怎么辦?必須重新編譯Servlet,而這樣就會大量增加開發(fā)人員的工作量,所以可以先將其作為Servlet的初始化參數(shù)配置到web.xml中。
Servlet初始化參數(shù)的創(chuàng)建和使用步驟如下:
(1)在web.xml中配置Servlet
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度智慧農(nóng)業(yè)項(xiàng)目承包合同10篇
- 2025年度海參養(yǎng)殖基地環(huán)境保護(hù)與生態(tài)補(bǔ)償合同3篇
- 2025年度昌平區(qū)校園食堂承包項(xiàng)目競爭性磋商合同3篇
- 2025年度新能源汽車充電車位分期付款租賃合同4篇
- 2025年度現(xiàn)代化豬欄設(shè)施租賃合同3篇
- 2025年度商業(yè)物業(yè)承包經(jīng)營合同范本4篇
- 2025年度新能源汽車融資租賃合同范本3篇
- 2025年度寵物店寵物購買合同附寵物用品租賃服務(wù)合同3篇
- 2025年度海綿城市建設(shè)項(xiàng)目特許經(jīng)營合同3篇
- 2025年度商業(yè)步行街?jǐn)偽蛔赓U及商業(yè)管理合同4篇
- 亞硝酸鈉安全標(biāo)簽
- pcs-985ts-x說明書國內(nèi)中文版
- GB 11887-2012首飾貴金屬純度的規(guī)定及命名方法
- 小品《天宮賀歲》臺詞劇本手稿
- 醫(yī)院患者傷口換藥操作課件
- 欠薪強(qiáng)制執(zhí)行申請書
- 礦山年中期開采重點(diǎn)規(guī)劃
- 資源庫建設(shè)項(xiàng)目技術(shù)規(guī)范匯編0716印刷版
- GC2級壓力管道安裝質(zhì)量保證體系文件編寫提綱
- 預(yù)應(yīng)力混凝土簡支小箱梁大作業(yè)計(jì)算書
- 燃燒機(jī)論文定型機(jī)加熱論文:天然氣直燃熱風(fēng)技術(shù)在定型機(jī)中的應(yīng)用
評論
0/150
提交評論