Servlet2.3中文文檔(第8,9,10章)
第八章 Dispatching Requests
當(dāng)建立一個(gè)web應(yīng)用時(shí),把一個(gè)請(qǐng)求傳給另一個(gè)servlet或在response中包含另一個(gè)servlet的輸出是經(jīng)常
使用的。RequestDispatcher接口就提供了一些方法。
8.1 獲得RequestDispatcher
實(shí)現(xiàn)了接口RequesetDispatcher接口的對(duì)象可以在ServletContext的getRequestDispatcher或
getNamedDispatchcer方法得到。
getRequestDispatcher的參數(shù)是一個(gè)以根目錄‘/’開始的一個(gè)路徑,該方法會(huì)查找路徑下的servlet,并把
它封裝成RequestDispatchcer對(duì)象返回。
getNamedDispatcher方法把一個(gè)ServletContext知道的servlet名字作為參數(shù),如果找到servlet,該
servlet就被封裝成RequestDispatcher對(duì)象返回,如果沒有找到則返回null。
RequestDispatcher對(duì)象中使用相對(duì)路徑也是可以的。在ServletRequest中提供了getRequestDispatcher
方法;這個(gè)方法和ServletContext中同名的方法功能類似。servlet引擎會(huì)用request的信息把相對(duì)路徑轉(zhuǎn)
化成完整路徑的。如ServleltRequest.getRequestDispatcher("header.html")和ServletConext.
getRequestDispatcher("/garden/headere.html")是等效的。
8.1.1 在Request Dispatcher 路徑中附加字符串
在ServletContext和ServletRequest創(chuàng)建RequestDispatcher方法中參數(shù)都可以帶字符串如:
Context.getRequestDispatcher("/raisons.jsp?orderno=5");
8.2 Request Dispatcher的使用
對(duì)于使用Request Dispatcher 而言就是一個(gè)servlet調(diào)用include或forward方法,這些方法的參數(shù)是
Servlet接口傳來(lái)的request和response對(duì)象實(shí)例。引擎必須確保調(diào)用Request Dispatcher的處理過(guò)程是在
同一個(gè)JVM的同一個(gè)線程中。
8.3 include 方法
RequestDispatcher接口的include方法可以在任何時(shí)候被調(diào)用;目標(biāo)servlet可以包含所有外的request對(duì)
象,不過(guò)response對(duì)象的使用是有限制的:
response只能寫信息到ServletOutputStream 或者Writer中,調(diào)用response對(duì)象的flushBuffer方法進(jìn)行提
交。不能夠設(shè)置頭信息,任何方法都不會(huì)影響到response的頭信息。
8.3.1 被包含的request參數(shù)
除了可以用getNamedDispatcher方法包含一個(gè)servlet外,以下的屬性可以被設(shè)置:
Java.servlet.include.request_uri
Java.servlet.include.context_path
Java.servlet.include.servlet_path
Java.servlet.include.path_info
Java.servlet.include.query_string
用request對(duì)象的getAttribute方法可以獲取被包含servlet的以上屬性。
如果被包含的servlet能后通過(guò)getNamedDispatcher方法找到就不必設(shè)置以上屬性了。
8.4 Forward 方法
RequestDispatcher接口中的forward方法,只有servlet沒有提交響應(yīng)到客戶端時(shí)才可用;如果響應(yīng)
buffer中有數(shù)據(jù)還沒有提交,當(dāng)調(diào)用forward方法中目標(biāo)servlet的service方法前,buffer中的內(nèi)容會(huì)被清
空;如果buffer中的數(shù)據(jù)提交了,則發(fā)生IllegalStateException錯(cuò)誤。
request對(duì)象的路徑必須放映獲取RequestDispatcher對(duì)象的路徑。
有個(gè)例外,如果RequestDispatcher是通過(guò)getNamedDispatcher方法得到的,request對(duì)象必須反映原始
request的路徑。
在RequestDispatcher接口方法forward返回前,response的內(nèi)容必須被提交,并由引擎關(guān)閉該servlet。
8.4.1 query String
在Request Dispatcher中創(chuàng)建的路徑是可以帶參數(shù)的。
8.5 錯(cuò)誤
如果request Dispatcher的目標(biāo)servlet拋出運(yùn)行時(shí)錯(cuò)誤或ServletException 或IOException,錯(cuò)誤就會(huì)被
傳給調(diào)用的servlet;在上傳之到調(diào)用的servlet之前,所有其他的exception都應(yīng)該包裝成
ServletExceptions。
第九章 web 應(yīng)用
一個(gè)web應(yīng)用是一堆servlet,html頁(yè)面,類和其他資源的集合。web應(yīng)用可以被發(fā)布運(yùn)行在很多服務(wù)提
供商的多種引擎下。
9.1 web服務(wù)器
在web服務(wù)中一個(gè)web應(yīng)用的根目錄是一個(gè)特殊的路徑,例如:一個(gè)網(wǎng)站目錄可以以http://www.
mycorp.com/登錄,所有的請(qǐng)求都將以這個(gè)作為前綴發(fā)送到以這個(gè)前綴描述的servletContext環(huán)境中。
在任何時(shí)候一個(gè)web應(yīng)用的實(shí)例只能運(yùn)行在一個(gè)JVM中。
9.2 和servletContext的關(guān)系
servlet引擎會(huì)強(qiáng)迫web應(yīng)用和ServletContext的通信,一個(gè)ServletContext對(duì)象提供了一個(gè)servlet使得該
應(yīng)用可見。
9.3 web應(yīng)用中的元素
一個(gè)web應(yīng)用包含以下的元素:
.Servlets
.JSP
.Utility Classes
.Static documents(html,images,sounds,etc)
.Client side Java applets,beans,and classes
.Descriptive meta informateion
9.4 部署層次
這個(gè)協(xié)議定義了一個(gè)層次結(jié)構(gòu),用于部署和打包,這個(gè)結(jié)構(gòu)存在于一個(gè)文件中。
9.5 目錄結(jié)構(gòu)
一個(gè)web應(yīng)用存在一個(gè)目錄層次結(jié)構(gòu)。文件根目錄是應(yīng)用的一部分。例如:一個(gè)web應(yīng)用的上下文路徑
是/catalog,web應(yīng)用的index.html文件就能被/catalog/index.html請(qǐng)求訪問(wèn)。URL和上下文路徑的匹配
規(guī)則將在11章討論。servlet引擎必須拒絕一個(gè)具有現(xiàn)在沖突的上下文路徑的web應(yīng)用,這種情況是有
的,如:兩個(gè)web應(yīng)用發(fā)布在同一個(gè)上下文路徑中,或一個(gè)web應(yīng)用的上下文路徑是另一個(gè)web應(yīng)用上
下文路徑的子路徑。
有一個(gè)特殊的目錄(“WEB-INF”)在應(yīng)用中存在,這個(gè)目錄包含所有與應(yīng)用相關(guān),又不在根目錄中的事
物。可以直接被引擎提供給客戶端的文件不放在WEB-INF中,但WEB-INF目錄對(duì)于調(diào)用ServletContext
的getResource和getResourceAsStream方法的servlet 代碼是有效的。如果開發(fā)者想用servlet代碼調(diào)用
一個(gè)不希望暴露給客戶端的一個(gè)配置信息,就可以把這個(gè)配置信息放在WEB-INF目錄下。請(qǐng)求都是和資
源相匹配的;敏感的匹配如客戶端的請(qǐng)求是“/WEB-INF/foo”和“/Web-iNf/foo”,但不應(yīng)該把定位于/
WEB-INF下的內(nèi)容作為結(jié)果返回。
WEB-INF目錄下的內(nèi)容有:
./WEB-INF/web.xml 部署描述文件
./WEB-INF/classes/ 存放servlet class
./WEB-INF/lib/*.jar 是jar包的目錄
應(yīng)用的classloader先load WEB-INF/classes目錄下的class后load WEB-INF/lib目錄下的jar包
9.5.1 目錄結(jié)構(gòu)的一個(gè)例子
一個(gè)簡(jiǎn)單web應(yīng)用的目錄結(jié)構(gòu):
/index.html
/howto.jsp
/images/banner.gif
/images/jumping.gif
/WEB-INF/web.xml
/WEB-INF/lib/jspbean.jar
/WEB-INF/classes/com/mycorp/servlets/MyServlet.class
/WEB-INF/classes/com/util/MyUtils.class
9.6 web應(yīng)用的存檔文件
一個(gè)web應(yīng)用可以被java打包工具打包成war文件,當(dāng)被打包后包中就會(huì)有一個(gè)額外META-INF目錄,該
目錄下存放了打包工具的一些信息。
9.7 web應(yīng)用部署描述
下面是web應(yīng)用部署描述中的配置類型:
.ServletContext Init Parameters
.Session Configuration
.Servlet / JSP Definitions
.Servlet / JSP Mappings
.MIME Type Mappings
.Welcome File list
.Error Pages
.Security
9.7.1 可靠的擴(kuò)展
web容器須提供一種機(jī)制使得web應(yīng)用知道jar文件中包含的有用資源或代碼。
引擎因該提供編輯、配置庫(kù)文件的程序。
在WAR中提供一個(gè)MANIFEST.MF文件,描述擴(kuò)展名列表是比較好的。標(biāo)準(zhǔn)的JAR是應(yīng)該有的,這個(gè)文件
描述的擴(kuò)展名應(yīng)該遵循Http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html中的規(guī)
定。web容器應(yīng)該能夠識(shí)別WEB-INF/lib文件夾中的任何文件的擴(kuò)展名,如果不能夠識(shí)別就應(yīng)該拒絕該
應(yīng)用程序,并報(bào)出錯(cuò)誤。
9.7.2 web應(yīng)用的classloader
引擎用于裝載war中的servlet的裝載器必須能夠讓開發(fā)者裝載jar庫(kù)中的任何資源。但裝載的資源禁止覆
蓋j2se或servlet API中的類;通常建議的做法是裝載器不允許war中的servlet去訪問(wèn)web引擎中的類。
還有一個(gè)被推薦的做法是實(shí)現(xiàn)應(yīng)用類裝載器,war中被裝載的類或資源就會(huì)被放到container-wide JAR庫(kù)
的特定類或資源中。
9.8 替換web應(yīng)用
一個(gè)服務(wù)器可能會(huì)在不重新啟動(dòng)引擎的情況下用一個(gè)新版本的應(yīng)用替換原有的應(yīng)用。當(dāng)一個(gè)應(yīng)用被替換
時(shí),引擎應(yīng)提供一個(gè)robust方法去保存該應(yīng)用中的session
9.9 錯(cuò)誤句柄
9.9.1 request Attributes
web應(yīng)用必須列出在使用中資源發(fā)生的錯(cuò)誤,這些資源在部署描述中都有定義。
如果錯(cuò)誤在一個(gè)servlet或一個(gè)jsp頁(yè)面中發(fā)生,則在第9.1章中的如下的請(qǐng)求屬性就會(huì)被設(shè)置:
Request Attributes Type
Javax.servlet.error.status_code java.lang.Integer
Javax.servlet.error.exception_type java.lang.Class
Javax.servlet.error.message java.lang.String
Javax.servlet.error.exception java.lang.Throwable
Javax.servlet.error.request_uri java.lang.String
Javax.servlet.error.servlet_name java.lang.String
這些屬性允許這個(gè)servlet根據(jù)這些狀態(tài)碼、錯(cuò)誤類型、錯(cuò)誤信息、被拋出的錯(cuò)誤對(duì)象、錯(cuò)誤產(chǎn)生的
servlet被訪問(wèn)的URI(可以用getRequestURI得到)、或錯(cuò)誤產(chǎn)生的servlet的邏輯名稱產(chǎn)生特殊的內(nèi)
容。
在2.3版本中錯(cuò)誤類型和錯(cuò)誤信息屬性是多余的,他們被保留只是為了向下兼容以前的版本。
9.9.2 錯(cuò)誤頁(yè)面
當(dāng)一個(gè)servlet產(chǎn)生錯(cuò)誤時(shí),開發(fā)者可以訂制錯(cuò)誤內(nèi)容返回給客戶端。部署描述文件定義了一個(gè)錯(cuò)誤頁(yè)面
列表。servlet在response中設(shè)置錯(cuò)誤狀態(tài)碼或產(chǎn)生的異常或錯(cuò)誤被引擎支持時(shí),引擎就會(huì)從部署描述文
件中調(diào)用相應(yīng)的配置的錯(cuò)誤資源。
如果一個(gè)錯(cuò)誤碼被設(shè)置在了response中,引擎在部署描述文件的錯(cuò)誤頁(yè)面列表中用status-code方式匹配
對(duì)應(yīng)的資源,如果找到就調(diào)用本地的資源。
在一個(gè)請(qǐng)求被處理的過(guò)程中servlet可以拋出以下的異常:
.runtime exceptions or errors
.ServletExceptions or subclasses thereof
.IOException or subclasses thereof
web應(yīng)用可以用exception-type元素來(lái)描述錯(cuò)誤頁(yè)面,在這種情況下引擎會(huì)通過(guò)比較用exception-type元
素定義的error-page列表中的異常來(lái)匹配產(chǎn)生的異常。匹配的結(jié)果是返回定義的與錯(cuò)誤匹配的本地資
源。在繼承類中,最近的類將被調(diào)用。
如果沒有一個(gè)error-page包含的exception-type與class-heirarchy相匹配。拋出的ServletException或其子
類異常,被引擎通過(guò)ServletException.getRootCause方法獲得,獲得后用這個(gè)異常再去配置的error
page列表中去匹配。
在部署描述文件中用exception-type元素定義的Error-page中exception-type的類名必須是唯一的。
當(dāng)錯(cuò)誤發(fā)生在servlet調(diào)用的RequestDispatcher中時(shí)error page機(jī)制是不能夠干預(yù)到的;這樣的情況如:
一個(gè)servlet用RequestDispatcher去調(diào)用另一個(gè)有錯(cuò)誤的servlet。
如果一個(gè)servlet產(chǎn)生的錯(cuò)誤沒有被描述的錯(cuò)誤頁(yè)面機(jī)制所抓到,引擎必須設(shè)置response的狀態(tài)碼為500
9.10 Welcome Files
web應(yīng)用可以在部署描述文件中定義一個(gè)welcome files調(diào)用的URI列表,這個(gè)機(jī)制的目的是允許開發(fā)者
定義自己的訪問(wèn)首頁(yè)。
如果沒有在部署描述中配置welcome 文件,引擎將把局部請(qǐng)求(沒有指明具體訪問(wèn)資源,如www.cacolg.
com/index.html,請(qǐng)求訪問(wèn)時(shí)用www.cacolg.com/訪問(wèn)的)發(fā)送到適當(dāng)?shù)馁Y源中,如:一個(gè)可能默認(rèn)的
servlet,或列出該目錄下的文件列表,或返回404響應(yīng)錯(cuò)誤。
一個(gè)例子:
1)在部署描述中定義index.html和default.jsp為welcome files
2)定義一個(gè)servlet的mapping路徑為/foo/
WAR中有的文件如下:
/foo/index.html
/foo/default.html
/foo/orderform.html
/foo/home.gif
/catalog/default.jsp
/catalog/products/shop.jsp
/catalog/products/register.jsp
3)請(qǐng)求的URI為 處理后的URI
/foo 或 /foo/ /foo/index.html
/catalog/ /catalog/default.jsp
/catalog/index.html 404 not found
/catalog/products/ 404 not found 也可能返回shop.jsp and /or register.jsp 列表。
9.11 web應(yīng)用環(huán)境
j2EE定義的命名環(huán)境能夠使得應(yīng)用在不需要知道外部信息怎么命名的情況下比較方便的訪問(wèn)資源或外部
信息。
servlet作為j2EE完整的一部分,使web應(yīng)用部署描述文件提供了一個(gè)servlet可以訪問(wèn)資源和EJB,這些
部署描述元素有:
.env-entry
.ejb-ref
.ejb-local-ref
.resource-ref
.resource-env-ref
開發(fā)者使用這些元素描述web應(yīng)用中需要用到的對(duì)象,這些對(duì)象都要在web容器運(yùn)行時(shí)注冊(cè)到JNDI命名
空間。
在J2EE1.3版本j2EE的環(huán)境需求中,servlet引擎不是J2EE技術(shù)的一部分,web環(huán)境要提供的功能在J2EE
規(guī)范中有描述。如果沒有實(shí)現(xiàn)支持環(huán)境所要提供的功能,在發(fā)布應(yīng)用時(shí),web容器就會(huì)拋出警告。
實(shí)現(xiàn)servlet引擎在J2EE中是需要的,應(yīng)該被納入J2EE1.3中。J2EE1.3應(yīng)該提供更多的內(nèi)容。
servlet引擎必須支持對(duì)象的lookup方法,查找對(duì)象并在引擎控制的線程中實(shí)例化。
servlet引擎應(yīng)該支持開發(fā)者創(chuàng)建的線程,因?yàn)閼?yīng)用創(chuàng)建的線程不是很輕便,開開發(fā)者不得不依賴于這些
功能有限的線程。這些需求將被加入到下一個(gè)版本的servlet規(guī)范中。
第十章 應(yīng)用周期事件
10.1 介紹
事件是servlet2.3種新添的內(nèi)容。應(yīng)用事件使得web開發(fā)者能夠控制ServletContext和HttpSession對(duì)象的
信息交互,使得管理web使用的資源更有效,方便。
10.2 事件監(jiān)聽器
事件監(jiān)聽器是實(shí)現(xiàn)了servlet事件監(jiān)聽接口的類。在web發(fā)布是這些監(jiān)聽類就被實(shí)例化和注冊(cè)在web容器
中。
servlet事件監(jiān)聽器提供了在ServletContext和HttpSerssion對(duì)象狀態(tài)發(fā)生改變時(shí)觸發(fā)的事件。Servlet
cotext監(jiān)聽器用于管理應(yīng)用的資源或虛擬機(jī)的狀態(tài)。HTTP session監(jiān)聽器管理與會(huì)話關(guān)聯(lián)的資源。
可以有多個(gè)監(jiān)聽器監(jiān)聽每一個(gè)事件類型。開發(fā)者可以指定引擎調(diào)用監(jiān)聽類的順序。
10.2.1 事件類型和監(jiān)聽接口
Event Type ListenerInterface 說(shuō)明
Lifecycle javax.servlet.ServletContextListener 當(dāng)servlet context被創(chuàng)建并有效的
接受第一個(gè)請(qǐng)或servlet context銷毀前
Changes to attributees javax.servlet.ServletContextAttributesListener 當(dāng)servlet context中的屬性發(fā)生
added,removed,replaced
Lifecycle javax.servlet.http.HttpSessionListener 當(dāng)HttpSession被創(chuàng)建,無(wú)效或超時(shí)
Changes to attributes javax.servlet.HttpSessionAttributesListener 當(dāng)屬性added,removed或replaced時(shí)
10.2.2 一個(gè)使用監(jiān)聽的例子
一個(gè)簡(jiǎn)單的web應(yīng)用中有servlet要訪問(wèn)數(shù)據(jù)庫(kù),開發(fā)者提供一個(gè)context 監(jiān)聽類管理數(shù)據(jù)庫(kù)連接。
1)web應(yīng)用啟動(dòng)時(shí),監(jiān)聽類被裝載,登陸數(shù)據(jù)庫(kù),在servlet context中保存數(shù)據(jù)庫(kù)連接。
2)servlet訪問(wèn)數(shù)據(jù)庫(kù)連接
3)當(dāng)web服務(wù)銷毀時(shí),或應(yīng)用從web服務(wù)中刪除時(shí),關(guān)閉數(shù)據(jù)庫(kù)連接。
10.3 監(jiān)聽類的配置
10.3.1 對(duì)監(jiān)聽類的規(guī)定
web開發(fā)者提供實(shí)現(xiàn)了以上監(jiān)聽接口的類,每個(gè)類應(yīng)該有一個(gè)沒有參數(shù)的構(gòu)造器函數(shù)。監(jiān)聽類放在
WEB-INF/classes下或以一個(gè)jar文件放在WEB-INF/lib下都可以。
10.3.2 部署描述
web容器對(duì)每個(gè)監(jiān)聽類只會(huì)創(chuàng)建一個(gè)實(shí)例,在第一個(gè)請(qǐng)求到來(lái)之前實(shí)例化并注冊(cè)。web容器注冊(cè)監(jiān)聽類
的順序根據(jù)他們實(shí)現(xiàn)的接口和在部署描述文件中定義的順序。web應(yīng)用調(diào)用監(jiān)聽實(shí)例的順序按照他們注
冊(cè)的順序。
10.3.4 在銷毀時(shí)的事件
當(dāng)應(yīng)用銷毀時(shí)監(jiān)聽事件的執(zhí)行順序按部署描述中的順序,先執(zhí)行session中的監(jiān)聽事件再執(zhí)行context中
的監(jiān)聽事件。session的無(wú)效事件必須在context的銷毀事件之前被調(diào)用。
10.4 部署描述的例子
下面給出注冊(cè)兩個(gè)servlet cocntext lifecycle監(jiān)聽器和一個(gè)HttpSession監(jiān)聽器的例子。
Com.acme.MyconnectionManager和com.acme.MyLoggingMoudule都實(shí)現(xiàn)了javax.
servletServletContextListener接口,com.acme.MyloggingModule另外還實(shí)現(xiàn)了javax.servlet.
HttpSessionListener接口。開發(fā)者希望com.acme.MyConnectionManager在com.acme.
MyLoggingModule之前管理者servlet context 的生命周期事件。部署描述文件如下:
<web-app>
<display-name>MyListeningApplication</display-name>
<listener>
<listener-class>com.acme.MyConnectionManager</listener-class>
</listenrer>
<listenrer>
<listenrer-class>com.acme.MyLoggingModele</listener-class>
</listener>
<sevlet>
<display-name>RegistrationServlet</display-name>
..etc
</servlet>
</web-app>
10.5 監(jiān)聽器的實(shí)例和線程
在第一個(gè)請(qǐng)求被web容器接受之前實(shí)例化并注冊(cè)好監(jiān)聽器類是必須的。監(jiān)聽器在整個(gè)web應(yīng)用生命周期
中都要使用。
ServletContext和HttpSession對(duì)象屬性的改變可能會(huì)同時(shí)產(chǎn)生,引擎不需要同步這些屬性類的事件。
10.6 分布式容器組
在分布式web容器組中,HttpSession和ServletContext實(shí)例只活動(dòng)與它們本地的JVM中。在分布式web容
器中,監(jiān)聽實(shí)例會(huì)在每一個(gè)web容器中創(chuàng)建實(shí)例。
10.7 session事件
監(jiān)聽器使得開發(fā)者可以跟蹤web應(yīng)用中的session。知道session是否變得無(wú)效是經(jīng)常被用到的,因?yàn)?br>session超時(shí)時(shí)引擎會(huì)使session變得無(wú)效,或應(yīng)用會(huì)調(diào)用invalidate方法。
posted on 2007-08-20 17:43 朱巖 閱讀(426) 評(píng)論(0) 編輯 收藏 所屬分類: servlet文章