用web.xml控制Web應用的行爲(4)

用web.xml控制Web應用的行爲(4)
2008-06-23 15:27
5.3 提供應用範圍內的初始化參數 
一般,對單個地servlet或JSP頁面分配初始化參數。指定的servlet或JSP頁面利用ServletConfig的 getInitParameter方法讀取這些參數。但是,在某些情形下,希望提供可由任意servlet或JSP頁面藉助ServletContext 的getInitParameter方法讀取的系統範圍內的初始化參數。 
可利用context-param元素聲明這些系統範圍內的初始化值。context-param元素應該包含param-name、param-value以及可選的description子元素,如下所示: 
<context-param> 
<param-name>support-email</param-name> 
<param-value>[email protected]</param-value> 
</context-param> 
可回憶一下,爲了保證可移植性,web.xml內的元素必須以正確的次序聲明。但這裏應該注意,context-param元素必須出現任意與文檔有關的 元素(icon、display-name或description)之後及filter、filter-mapping、listener或 servlet元素之前。 
5.4 在服務器啓動時裝載servlet 
假如servlet或JSP頁面有一個要花很長時間執行的init(servlet)或jspInit(JSP)方法。例如,假如init或jspInit方法從某個數據庫或ResourceBundle查找產量。這種情況下,在第一個客戶機請求時裝載servlet的缺省行爲將對第一個客戶機產生較長時間的延遲。因此,可利用servlet的load-on-startup元素規定服務器在第一次啓動時裝載servlet。下面是一個例子。 
<servlet> 
<servlet-name> … </servlet-name> 
<servlet-class> … </servlet-class> <!-- Or jsp-file --> 
<load-on-startup/> 
</servlet> 
可以爲此元素體提供一個整數而不是使用一個空的load-on-startup。想法是服務器應該在裝載較大數目的servlet或JSP頁面之前裝載較少數目的servlet或JSP頁面。例如,下面的servlet項(放置在Web應用的WEB-INF目錄下的web.xml文件中的web-app元素內)將指示服務器首先裝載和初始化SearchServlet,然後裝載和初始化由位於Web應用的result目錄中的index.jsp文件產生的servlet。 
<servlet> 
<servlet-name>Search</servlet-name> 
<servlet-class>myPackage.SearchServlet</servlet-class> <!-- Or jsp-file --> 
<load-on-startup>1</load-on-startup> 
</servlet> 
<servlet> 
<servlet-name>Results</servlet-name> 
<servlet-class>/results/index.jsp</servlet-class> <!-- Or jsp-file --> 
<load-on-startup>2</load-on-startup> 
</servlet>

6 聲明過濾器

servlet版本2.3引入了過濾器的概念。雖然所有支持servlet API版本2.3的服務器都支持過濾器,但爲了使用與過濾器有關的元素,必須在web.xml中使用版本2.3的DTD。 
過濾器可截取和修改進入一個servlet或JSP頁面的請求或從一個servlet或JSP頁面發出的相應。在執行一個servlet或JSP頁面之 前,必須執行第一個相關的過濾器的doFilter方法。在該過濾器對其FilterChain對象調用doFilter時,執行鏈中的下一個過濾器。如 果沒有其他過濾器,servlet或JSP頁面被執行。過濾器具有對到來的ServletRequest對象的全部訪問權,因此,它們可以查看客戶機名、 查找到來的cookie等。爲了訪問servlet或JSP頁面的輸出,過濾器可將響應對象包裹在一個替身對象(stand-in object)中,比方說把輸出累加到一個緩衝區。在調用FilterChain對象的doFilter方法之後,過濾器可檢查緩衝區,如有必要,就對它 進行修改,然後傳送到客戶機。 
例如,程序清單5-11帝國難以了一個簡單的過濾器,只要訪問相關的servlet或JSP頁面,它就截取請求並在標準輸出上打印一個報告(開發過程中在桌面系統上運行時,大多數服務器都可以使用這個過濾器)。

程序清單5-11 ReportFilter.java 
package moreservlets;

import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.util.*;

/** Simple filter that prints a report on the standard output 
* whenever the associated servlet or JSP page is accessed. 
* <P> 
* Taken from More Servlets and JavaServer Pages 
* from Prentice Hall and Sun Microsystems Press, 
* http://www.moreservlets.com/. 
* © 2002 Marty Hall; may be freely used or adapted. 
*/

public class ReportFilter implements Filter { 
public void doFilter(ServletRequest request, 
ServletResponse response, 
FilterChain chain) 
throws ServletException, IOException { 
HttpServletRequest req = (HttpServletRequest)request; 
System.out.println(req.getRemoteHost() + 
" tried to access " + 
req.getRequestURL() + 
" on " + new Date() + "."); 
chain.doFilter(request,response); 
}

public void init(FilterConfig config) 
throws ServletException { 
}

public void destroy() {} 
}

一 旦建立了一個過濾器,可以在web.xml中利用filter元素以及filter-name(任意名稱)、file-class(完全限定的類名)和 (可選的)init-params子元素聲明它。請注意,元素在web.xml的web-app元素中出現的次序不是任意的;允許服務器(但不是必需的)強制所需的次序,並且實際中有些服務器也是這樣做的。但這裏要注意,所有filter元素必須出現在任意filter-mapping元素之前,filter-mapping元素又必須出現在所有servlet或servlet-mapping元素之前。 
例如,給定上述的ReportFilter類,可在web.xml中作出下面的filter聲明。它把名稱Reporter與實際的類ReportFilter(位於moreservlets程序包中)相關聯。
<filter> 
<filter-name>Reporter</filter-name> 
<filter-class>moresevlets.ReportFilter</filter-class> 
</filter> 
一旦命名了一個過濾器,可利用filter-mapping元素把它與一個或多個servlet或JSP頁面相關聯。關於此項工作有兩種選擇。 
首先,可使用filter-name和servlet-name子元素把此過濾器與一個特定的servlet名(此servlet名必須稍後在相同的 web.xml文件中使用servlet元素聲明)關聯。例如,下面的程序片斷指示系統只要利用一個定製的URL訪問名爲SomeServletName 的servlet或JSP頁面,就運行名爲Reporter的過濾器。 
<filter-mapping> 
<filter-name>Reporter</filter-name> 
<servlet-name>SomeServletName</servlet-name> 
</filter-mapping> 
其次,可利用filter-name和url-pattern子元素將過濾器與一組servlet、JSP頁面或靜態內容相關聯。例如,相面的程序片段指示系統只要訪問Web應用中的任意URL,就運行名爲Reporter的過濾器。 
<filter-mapping> 
<filter-name>Reporter</filter-name> 
<url-pattern>/*</url-pattern> 
</filter-mapping> 
例如,程序清單5-12給出了將ReportFilter過濾器與名爲PageName的servlet相關聯的web.xml文件的一部分。名字 PageName依次又與一個名爲TestPage.jsp的JSP頁面以及以模式http: //host/webAppPrefix/UrlTest2/ 開頭的URL相關聯。TestPage.jsp的源代碼已經JSP頁面命名的談論在前面的3節"分配名稱和定製的URL"中給出。事實上,程序清單5- 12中的servlet和servlet-name項從該節原封不動地拿過來的。給定這些web.xml項,可看到下面的標準輸出形式的調試報告(換行是 爲了容易閱讀)。 
audit.irs.gov tried to access 
http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html 
on Tue Dec 25 13:12:29 EDT 2001.

程序清單5-12 Web.xml(說明filter用法的摘錄) 
<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE web-app 
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app> 
<filter> 
<filter-name>Reporter</filter-name> 
<filter-class>moresevlets.ReportFilter</filter-class> 
</filter> 
<!-- ... --> 
<filter-mapping> 
<filter-name>Reporter</filter-name> 
<servlet-name>PageName</servlet-name> 
</filter-mapping> 
<!-- ... --> 
<servlet> 
<servlet-name>PageName</servlet-name> 
<jsp-file>/RealPage.jsp</jsp-file> 
</servlet> 
<!-- ... --> 
<servlet-mapping> 
<servlet-name> PageName </servlet-name> 
<url-pattern>/UrlTest2/*</url-pattern> 
</servlet-mapping> 
<!-- ... --> 
</web-app>

7 指定歡迎頁

假 如用戶提供了一個像http://host/webAppPrefix/directoryName/ 這樣的包含一個目錄名但沒有包含文件名的URL,會發生什麼事情呢?用戶能得到一個目錄表?一個錯誤?還是標準文件的內容?如果得到標準文件內容,是 index.html、index.jsp、default.html、default.htm或別的什麼東西呢? 
Welcome-file-list元素及其輔助的welcome-file元素解決了這個模糊的問題。例如,下面的web.xml項指出,如果一個URL給出一個目錄名但未給出文件名,服務器應該首先試用index.jsp,然後再試用index.html。如果兩者都沒有找到,則結果有賴於所用的服務器(如一個目錄列表)。 
<welcome-file-list> 
<welcome-file>index.jsp</welcome-file> 
<welcome-file>index.html</welcome-file> 
</welcome-file-list> 
雖然許多服務器缺省遵循這種行爲,但不一定必須這樣。因此,明確地使用welcom-file-list保證可移植性是一種良好的習慣。

發佈了27 篇原創文章 · 獲贊 3 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章