<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 14,  comments - 37,  trackbacks - 0

    Servlet 2.3 規(guī)范的附加過濾為 J2EE 應(yīng)用程序提供了強(qiáng)化的性能

    新的 Java Servlet 2.3規(guī)范有不少最激動(dòng)人心的功能,其中之一便是過濾。乍一看,Servlet 2.3過濾似乎與 Apache、IIS、Netscape Web服務(wù)器及其它服務(wù)器中已有的傳統(tǒng)過濾器非常相似。事實(shí)上,Servlet 2.3過濾從結(jié)構(gòu)上來說是一個(gè)完全不同的設(shè)計(jì) -- 補(bǔ)充支持 Java平臺(tái)面向?qū)ο蟮奶匦裕蕴峁└呒?jí)別的性能。本文向您介紹了 Tomcat 4中的過濾,并展示了如何在項(xiàng)目中高效地使用過濾器。請(qǐng)點(diǎn)擊文章頂部或底部的 討論,參與 討論論壇,與本文作者和其他讀者分享您對(duì)本文的想法。

    過濾是 Tomcat 4 的新功能。(如想了解 Tomcat 的簡要?dú)v史,請(qǐng)參閱 Tomcat 的故事)。它是 Servlet 2.3 規(guī)范的一部分,并且最終將為所有支持此標(biāo)準(zhǔn)的 J2EE 容器的廠商所采用執(zhí)行。開發(fā)人員將能夠用過濾器來實(shí)現(xiàn)以前使用不便的或難以實(shí)現(xiàn)的功能,這些功能包括:

    • 資源訪問(Web 頁、JSP 頁、servlet)的定制身份認(rèn)證
    • 應(yīng)用程序級(jí)的訪問資源的審核和記錄
    • 應(yīng)用程序范圍內(nèi)對(duì)資源的加密訪問,它建立在定制的加密方案基礎(chǔ)上
    • 對(duì)被訪問資源的及時(shí)轉(zhuǎn)換,包括從 servlet 和 JSP 的動(dòng)態(tài)輸出

    這個(gè)清單當(dāng)然并沒有一一羅列,但它讓您初步體驗(yàn)到了過濾所帶來的額外價(jià)值。在本文中,我們將詳細(xì)討論 Servlet 2.3 的過濾,來看一看過濾器是如何配合 J2EE 處理模型的。不像其它傳統(tǒng)的過濾方案,Servlet 2.3 過濾是建立在 嵌套調(diào)用的基礎(chǔ)上的。我們來研究一下這一差別是怎樣在架構(gòu)上與新的高性能 Tomcat 4 設(shè)計(jì)取得一致的。最后,我們將獲得一些編寫及測(cè)試兩個(gè) Servlet 2.3 過濾器的實(shí)際經(jīng)驗(yàn)。這些過濾器只完成很簡單的功能,使我們得以將注意力集中于編寫過濾器以及如何將它們集成進(jìn) Web 應(yīng)用程序的機(jī)制。

    作為 Web 應(yīng)用程序構(gòu)建模塊的過濾器

    在物理結(jié)構(gòu)上,過濾器是 J2EE Web 應(yīng)用程序中的應(yīng)用程序級(jí)的 Java 代碼組件。除了 servlet 和 JSP 頁以外,遵循 Servlet 2.3 規(guī)范編碼的開發(fā)人員能將過濾器作為在 Web 應(yīng)用程序中加入活動(dòng)行為的機(jī)制。與在特定的 URL 上工作的 servlet 和 JSP 頁不同,過濾器接入 J2EE 容器的處理管道,并能跨越由 Web 應(yīng)用程序提供的 URL 子集(或所有 URL)進(jìn)行工作。圖 1 說明了過濾是在哪里配合 J2EE 請(qǐng)求處理的。



    圖 1. 過濾器與 J2EE 請(qǐng)求處理
    過濾器與 J2EE 請(qǐng)求處理

    兼容 Servlet 2.3 的容器允許過濾器在請(qǐng)求被處理(通過 Servlet 引擎) 以前以及請(qǐng)求得到處理 以后(過濾器將可以訪問響應(yīng))訪問 Web 請(qǐng)求。

    在這些情況下,過濾器可以:

    • 在請(qǐng)求得到處理以前修改請(qǐng)求的標(biāo)題
    • 提供它自己的請(qǐng)求版本以供處理
    • 在請(qǐng)求處理以后和被傳回給用戶以前修改響應(yīng)
    • 先取得由容器進(jìn)行的所有請(qǐng)求處理,并產(chǎn)生自己的響應(yīng)

    比過濾器的可用性更為重要的是,接入 J2EE 處理管道需要?jiǎng)?chuàng)建不可移植的、容器專用的和系統(tǒng)范圍的擴(kuò)展機(jī)制(如 Tomcat 3 攔截器)。





    回頁首


    概念上的 Tomcat 過濾

    不同于在 Apache、IIS 或 Netscape 服務(wù)器中能找到的熟悉的過濾機(jī)制,Servlet 2.3 過濾器并非建立在掛鉤式函數(shù)調(diào)用上。事實(shí)上, Tomcat 4 級(jí)別的引擎架構(gòu)脫離了傳統(tǒng)的 Tomcat 3.x 版本。新的 Tomcat 4 引擎取代了在請(qǐng)求處理的不同階段調(diào)用掛鉤式方法的整體式引擎,它在內(nèi)部使用了一系列的嵌套調(diào)用、包裝請(qǐng)求及響應(yīng)。不同的過濾器和資源處理器構(gòu)成了一個(gè)鏈。

    在傳統(tǒng)架構(gòu)中:

    • 每次接受到請(qǐng)求,掛鉤式方法就被調(diào)用,不論它們是否執(zhí)行(有時(shí)甚至是空的)。
    • 方法的作用域及并發(fā)關(guān)系(每個(gè)方法可能在不同的線程上被調(diào)用)不允許在處理相同的請(qǐng)求時(shí)簡單、高效地共享不同掛鉤式方法調(diào)用間的變量和信息。

    在新架構(gòu)中:

    • 嵌套的方法調(diào)用通過一系列過濾器實(shí)現(xiàn),它僅有應(yīng)用于當(dāng)前請(qǐng)求的過濾器組成;基于掛鉤式調(diào)用的傳統(tǒng)執(zhí)行方式需要在處理短句中調(diào)用掛鉤式例程,即使一個(gè)特定短句的處理邏輯不起任何作用。
    • 局部變量在實(shí)際的過濾方法返回之前都作保留,并且可用(因?yàn)樯嫌芜^濾器的調(diào)用總在堆棧上,等待后續(xù)調(diào)用的返回)。

    這一新架構(gòu)為今后的 Tomcat 性能調(diào)整與優(yōu)化提供了一個(gè)新的、更 對(duì)象友好的基礎(chǔ)。Servlet 2.3 過濾器是這個(gè)新的內(nèi)部架構(gòu)的自然擴(kuò)展。該架構(gòu)為 Web 應(yīng)用程序設(shè)計(jì)人員提供了一個(gè)可移植的執(zhí)行過濾行為的方法。





    回頁首


    調(diào)用鏈

    所有過濾器都服從調(diào)用的過濾器鏈,并通過定義明確的接口得到執(zhí)行。一個(gè)執(zhí)行過濾器的 Java 類必須執(zhí)行這一 javax.servlet.Filter 接口。這一接口含有三個(gè)過濾器必須執(zhí)行的方法:

    • doFilter(ServletRequest, ServletResponse, FilterChain) :這是一個(gè)完成過濾行為的方法。這同樣是上游過濾器調(diào)用的方法。引入的 FilterChain 對(duì)象提供了后續(xù)過濾器所要調(diào)用的信息。
    • init(FilterConfig) :這是一個(gè)容器所調(diào)用的初始化方法。它保證了在第一次 doFilter() 調(diào)用前由容器調(diào)用。您能獲取在 web.xml 文件中指定的初始化參數(shù)。
    • destroy() :容器在破壞過濾器實(shí)例前, doFilter() 中的所有活動(dòng)都被該實(shí)例終止后,調(diào)用該方法。

    請(qǐng)注意: Filter 接口的方法名及語義在最近的幾個(gè) beta 周期中曾有過不斷的改變。Servlet 2.3 規(guī)范仍未處于最后的草案階段。在 Beta 1 中,該接口包括 setFilterConfig()getFilterConfig() 方法,而不是 init()destroy()

    嵌套調(diào)用在 doFilter() 方法執(zhí)行中發(fā)生。除非您建立一個(gè)過濾器明確阻止所有后續(xù)處理(通過其它過濾器及資源處理器),否則過濾器一定會(huì)在 doFilter 方法中作以下的調(diào)用:

    FilterChain.doFilter(request, response);
                





    回頁首


    安裝過濾器:定義與映射

    容器通過 Web 應(yīng)用程序中的配置描述符 web.xml 文件了解過濾器。有兩個(gè)新的標(biāo)記與過濾器相關(guān): <filter><filter-mapping> 。應(yīng)該指定它們?yōu)?web.xml 文件內(nèi) <web-app> 標(biāo)記的子標(biāo)記。

    過濾器定義的元素

    <filter> 標(biāo)記是一個(gè)過濾器定義,它必定有一個(gè) <filter- name><filter-class> 子元素。 <filter-name> 子元素給出了一個(gè)與過濾器實(shí)例相關(guān)的、基于文本的名字。 <filter-class> 指定了由容器載入的實(shí)際類。您能隨意地包含一個(gè) <init-param> 子元素為過濾器實(shí)例提供初始化參數(shù)。例如,下面的過濾器定義指定了一個(gè)叫做 IE Filter 的過濾器:



    清單 1. 過濾器定義標(biāo)記
    <web-app>
                <filter>
                <filter-name>IE Filter</filter-name>
                <filter-class>com.ibm.devworks.filters.IEFilter</filter-class>
                </filter>
                </web-app>
                

    容器處理 web.xml 文件時(shí),它通常為找到的每個(gè)過濾器定義創(chuàng)建一個(gè)過濾器實(shí)例。這一實(shí)例用來服務(wù)所有的可用 URL 請(qǐng)求;因此,以線程安全的方式編寫過濾器是最為重要的。

    過濾器映射及子元素

    <filter-mapping> 標(biāo)記代表了一個(gè)過濾器的映射,指定了過濾器會(huì)對(duì)其產(chǎn)生作用的 URL 的子集。它必須有一個(gè) <filter-name> 子元素與能找到您希望映射的過濾器的過濾器定義相對(duì)應(yīng)。接下來,您可以使用 <servlet-name><url-pattern> 子元素來指定映射。 <servlet-name> 指定了一個(gè)過濾器應(yīng)用的 servlet (在 web.xml 文件中的其它地方已定義)。您能使用 <url-pattern> 來指定一個(gè)該過濾器應(yīng)用的 URL 的子集。例如, /* 的樣式用來代表該過濾器映射應(yīng)用于該應(yīng)用程序用到的每個(gè) URL,而 /dept/humanresources/* 的樣式則表明該過濾器映射只應(yīng)用于人力資源部專有的 URL。

    容器使用這些過濾器映射來確定一個(gè)特定的過濾器是否應(yīng)參與某個(gè)特定的請(qǐng)求。清單 1 是為應(yīng)用程序的所有 URL 定義的應(yīng)用于 IE Filter 的一個(gè)過濾器映射:



    清單 2. 過濾器映射標(biāo)記
    <filter-mapping>
                <filter-name>IE Filter</filter-name>
                <url-pattern>/*</url-pattern>
                </filter-mapping>
                





    回頁首


    創(chuàng)建一個(gè)簡單的過濾器

    現(xiàn)在該來定義我們的第一個(gè)過濾器了。這是一個(gè)不重要的過濾器,檢查請(qǐng)求標(biāo)題以確定是不是使用 Internet Explorer 瀏覽器來查看 URL 的。如果是 Internet Explorer 瀏覽器,過濾器就顯示“拒絕訪問”的信息。盡管操作并不重要,但這個(gè)示例演示了:

    • 一個(gè)過濾器的一般剖析
    • 一個(gè)在請(qǐng)求到達(dá)資源處理器前檢查其標(biāo)題信息的過濾器
    • 如何編寫一個(gè)過濾器來阻止基于運(yùn)行時(shí)間檢測(cè)到的條件(驗(yàn)證參數(shù)、源 IP、時(shí)間…等等)的后續(xù)處理

    此過濾器的源代碼作為 IEFilter.javacom.ibm.devworks.filters 包的一部分位于源代碼發(fā)布區(qū)中(請(qǐng)參閱 參考資料)。現(xiàn)在就讓我們來仔細(xì)研究一下該過濾器的代碼。



    清單 3. 使用 Filter 接口
    public final class IEFilter implements Filter {
                private FilterConfig filterConfig = null;
                


    所有的過濾器都須執(zhí)行 Filter 接口。我們創(chuàng)建了一個(gè)局部變量以容納由容器在初始化過濾器時(shí)傳遞進(jìn)來的 filterConfig 。這有時(shí)發(fā)生在第一次調(diào)用 doFilter() 前。



    清單 4. doFilter 方法
       public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain)
                throws IOException, ServletException {
                String browserDet =
                ((HttpServletRequest) request).getHeader("User-Agent").toLowerCase();
                if ( browserDet.indexOf("msie") != -1)  {
                PrintWriter out = response.getWriter();
                out.println("<html><head></head><body>");
                out.println("<h1>Sorry, page cannot be displayed!</h1>");
                out.println("</body></html>");
                out.flush();
                return;
                }
                

    doFilter() 完成了大部分工作。我們來檢查一下叫做“用戶代理”標(biāo)題的請(qǐng)求標(biāo)題。所有的瀏覽器都提供這個(gè)標(biāo)題。我們將其轉(zhuǎn)換成小寫字母,然后查找說明問題的標(biāo)識(shí)字符串 "msie"。如果檢測(cè)到了 Internet Explorer,我們就從響應(yīng)對(duì)象中獲取一個(gè) PrintWriter 來寫出自己的響應(yīng)。在寫出了定制的響應(yīng)后,方法無需連到其它過濾器就能返回。這就是過濾器阻止后續(xù)處理的方法。

    如果瀏覽器并非 Internet Explorer,我們就能進(jìn)行正常的鏈?zhǔn)讲僮鳎尯罄m(xù)過濾器和處理器能在得到請(qǐng)求時(shí)獲得執(zhí)行的機(jī)會(huì):



    清單 5. 進(jìn)行正常鏈?zhǔn)讲僮?/strong>
         chain.doFilter(request, response);
                }
                

    隨后,我們粗略地執(zhí)行該過濾器中的 init()destroy() 方法:



    清單 6. init() 和 destroy() 方法
       public void destroy() {
                }
                public void init(FilterConfig filterConfig) {
                this.filterConfig = filterConfig;
                }
                }
                





    回頁首


    測(cè)試 IEFilter

    假設(shè)您安裝了 Tomcat 4 beta 3 (或更新版本)并能使用,請(qǐng)按下列步驟啟動(dòng) IEFilter 并運(yùn)行:

    1. 在 $TOMCAT_HOME/conf 目錄下的 server.xml 文件里創(chuàng)建一個(gè)新的應(yīng)用程序上下文,如下所示:

             <!-- Tomcat Examples Context -->
                      <Context path="/examples" docBase="examples" debug="0"
                      reloadable="true">
                      ...
                      </Context>
                      <Context path="/devworks" docBase="devworks" debug="0"
                      reloadable="true">
                      <Logger className="org.apache.catalina.logger.FileLogger"
                      prefix="localhost_devworks_log." suffix=".txt"
                      timestamp="true"/>
                      </Context>
                      


    2. 編輯代碼區(qū)的 devworks/WEB-INF 下的 web.xml 文件,以包括下列的過濾器定義及映射:

      <web-app>
                      <filter>
                      <filter-name>IE Filter</filter-name>
                      <filter-class>com.ibm.devworks.filters.IEFilter</filter-class>
                      </filter>
                      <filter-mapping>
                      <filter-name>IE Filter</filter-name>
                      <url-pattern>/*</url-pattern>
                      </filter-mapping>
                      </web-app>
                      


    3. 在 $TOMCAT_HOME/webapps 目錄下創(chuàng)建一個(gè)叫做 devworks 的新目錄,并將所有 devworks 目錄下的東西(包括所有子目錄)從源代碼區(qū)復(fù)制到該位置。現(xiàn)在就準(zhǔn)備好啟動(dòng) Tomcat 4 了。

    4. 使用下面的 URL 來訪問一個(gè)簡單的 index.html 頁面: http://<hostname>/devworks/index.html

      如果您使用的是 Internet Explorer,就能看見如圖 2 所示的定制的“拒絕訪問”信息。



      圖 2. IEFilter 在遇到 Internet Explorer 的運(yùn)行效果
      IEFilter 在遇到 Internet Explorer 的運(yùn)行效果

      如果您使用的是 Netscape,那就能看見如圖 3 所示的確切的 HTML 頁面。



      圖 3. IEFilter 用 Netscape 瀏覽器的瀏覽效果
      IEFilter 用 Netscape 瀏覽器的瀏覽效果




    回頁首


    編寫轉(zhuǎn)換資源的過濾器

    現(xiàn)在該來試一下更復(fù)雜的過濾器了。該過濾器:

    • 從過濾器定義的實(shí)例初始化參數(shù)中讀取一組 "search" 及 "replace" 文本
    • 過濾被訪問的 URL,將出現(xiàn)的第一個(gè) "search" 文本替代為 "replace" 文本

    在我們深入研究這個(gè)過濾器的過程中,您將對(duì)內(nèi)容轉(zhuǎn)換/替代過濾器的架構(gòu)加深了解。相同的架構(gòu)能用于任何加密、壓縮及轉(zhuǎn)換(如由 XSLT 轉(zhuǎn)換來的 SML)過濾器。

    核心機(jī)密是在鏈?zhǔn)教幚淼倪^程中傳遞一個(gè)定制的響應(yīng)對(duì)象的包裝版本。該定制的包裝響應(yīng)對(duì)象須隱藏原響應(yīng)對(duì)象(從而對(duì)其實(shí)現(xiàn) 包裝),并提供一個(gè)定制的流以供后續(xù)處理器寫入。如果工作(文本替換、轉(zhuǎn)換、壓縮、加密…等)能迅速完成,定制流的執(zhí)行就能中止后續(xù)記錄并完成需要的工作。然后定制的流就會(huì)將經(jīng)轉(zhuǎn)換的數(shù)據(jù)寫入包裝的響應(yīng)對(duì)象(也就是說,簡單的字符替換加密)。如果工作無法迅速完成,定制的流就需等待,直到后續(xù)處理器完成對(duì)流的寫入(也就是說,當(dāng)其關(guān)閉或刷新流時(shí))。然后它才完成轉(zhuǎn)換工作,并將經(jīng)轉(zhuǎn)換的輸出結(jié)果寫入“真正的”響應(yīng)中。

    在我們的過濾器( ReplaceTextFilter )中,定制的包裝響應(yīng)對(duì)象叫作 ReplaceTextWrapper 。定制流的執(zhí)行叫做 ReplaceTextStream 。您能在 com.ibm.devworks.filters 包中的 ReplaceTextFilter.java 文件里找到源代碼。(請(qǐng)參閱 參考資料)。現(xiàn)在就讓我們來研究一下源代碼吧。



    清單 7. ReplaceTextStream 類
    class ReplaceTextStream extends ServletOutputStream {
                private OutputStream intStream;
                private ByteArrayOutputStream baStream;
                private boolean closed = false;
                private String origText;
                private String newText;
                public ReplaceTextStream(OutputStream outStream,
                String searchText,
                String replaceText) {
                intStream = outStream;
                baStream = new ByteArrayOutputStream();
                origText = searchText;
                newText = replaceText;
                }
                

    這是定制的輸出流代碼。 intStream 變量包含了對(duì)來自響應(yīng)對(duì)象的實(shí)際流的引用。 baStream 是我們輸出流的緩沖版本,后續(xù)處理器就寫入這里。 closed 標(biāo)記標(biāo)明了 close() 是否在此實(shí)例流中被調(diào)用。構(gòu)造器將來自響應(yīng)對(duì)象的流引用存儲(chǔ)起來并創(chuàng)建了緩沖流。它還將文本字符串存儲(chǔ)起來供以后的替代操作使用。



    清單 8. write() 方法
       public void write(int i) throws java.io.IOException {
                baStream.write(i);
                }
                

    我們須提供自己的源于 ServletOutputStreamwrite() 方法。在此,我們當(dāng)然是寫入緩沖流。所有來自后續(xù)處理器的更高級(jí)輸出方法都將以最低級(jí)別使用該方法,以保證所有的寫入都指向緩沖流。



    清單 9. close() 及 flush() 方法
       public void close() throws java.io.IOException {
                if (!closed) {
                processStream();
                intStream.close();
                closed = true;
                }
                }
                public void flush() throws java.io.IOException {
                if (baStream.size() != 0) {
                if (! closed) {
                processStream();           // need to synchronize the flush!
                baStream = new ByteArrayOutputStream();
                }
                }
                }
                

    close()flush() 方法是我們完成轉(zhuǎn)換的語句。根據(jù)后續(xù)處理器不同,其中的一個(gè)或兩個(gè)程序都有可能被調(diào)用。我們使用布爾型的 closed 標(biāo)識(shí)來避免異常情況。請(qǐng)注意,我們將實(shí)際的替代工作委托給了 processStream() 方法。



    清單 10. processStream() 方法
       public void processStream() throws java.io.IOException {
                intStream.write(replaceContent(baStream.toByteArray()));
                intStream.flush();
                }
                

    processStream() 方法將經(jīng)轉(zhuǎn)換的輸出結(jié)果從 baStream 寫入其已經(jīng)配有的 intStream 中去。轉(zhuǎn)換工作獨(dú)立于 replaceContent() 方法。



    清單 11. replaceContent() 方法
     public byte []  replaceContent(byte [] inBytes) {
                String retVal ="";
                String firstPart="";
                String tpString = new String(inBytes);
                String srchString = (new String(inBytes)).toLowerCase();
                int endBody = srchString.indexOf(origText);
                if (endBody != -1) {
                firstPart = tpString.substring(0, endBody);
                retVal = firstPart + newText +
                tpString.substring(endBody + origText.length());
                } else {
                retVal=tpString;
                }
                return retVal.getBytes();
                }
                }
                

    replaceContent() 是發(fā)生搜索與替換的語句。它將一個(gè)字節(jié)數(shù)組作為輸入并返回一個(gè)字節(jié)數(shù)組,創(chuàng)建一個(gè)原始的概念接口。事實(shí)上,我們能通過替換該方法中的邏輯部分來完成任何形式的轉(zhuǎn)換。這里,我們進(jìn)行非常簡單的文本替換。



    清單 12. ReplaceTextWrapper 類
    class ReplaceTextWrapper extends HttpServletResponseWrapper {
                private PrintWriter tpWriter;
                private ReplaceTextStream tpStream;
                public ReplaceTextWrapper(ServletResponse inResp, String searchText,
                String replaceText)
                throws java.io.IOException {
                super((HttpServletResponse) inResp);
                tpStream = new ReplaceTextStream(inResp.getOutputStream(),
                searchText,
                replaceText);
                tpWriter = new PrintWriter(tpStream);
                }
                public ServletOutputStream getOutputStream() throws java.io.IOException {
                return tpStream;
                }
                public PrintWriter getWriter() throws java.io.IOException {
                return tpWriter;
                }
                }
                

    我們定制的包裝響應(yīng)能方便地從幫助類 HttpServletResponseWrapper 中導(dǎo)出。這一類粗略地執(zhí)行許多方法,允許我們簡單地覆蓋 getOutputStream() 方法以及 getWriter() 方法,提供了定制輸出流的實(shí)例。



    清單 13. ReplaceTextWrapper() 方法
    public final class ReplaceTextFilter implements Filter {
                private FilterConfig filterConfig = null;
                private String searchText = ".";
                private String replaceText = ".";
                public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain)
                throws IOException, ServletException {
                ReplaceTextWrapper myWrappedResp = new ReplaceTextWrapper( response,
                searchText, replaceText);
                chain.doFilter(request,  myWrappedResp);
                myWrappedResp.getOutputStream().close();
                }
                public void destroy() {
                }
                

    最后,還有過濾器本身。它所做的不過是使用 FilterChain 為遞交響應(yīng)后續(xù)創(chuàng)建一個(gè)定制的包裝響應(yīng)實(shí)例,如下所示:



    清單 14. 創(chuàng)建一個(gè)定制的包裝響應(yīng)實(shí)例
       public void init(FilterConfig filterConfig) {
                String tpString;
                if (( tpString = filterConfig.getInitParameter("search") ) != null)
                searchText = tpString;
                if (( tpString = filterConfig.getInitParameter("replace") ) != null)
                replaceText = tpString;
                this.filterConfig = filterConfig;
                }
                }
                

    init 方法中,我們?nèi)』亓诉^濾器定義中指定的初始參數(shù)。 filterConfig 對(duì)象中的 getInitParameter() 方法便于用來實(shí)現(xiàn)這個(gè)目的。





    回頁首


    測(cè)試 ReplaceTextFilter

    假如您使用先前提及的步驟測(cè)試了 IEFilter ,并將所有文件復(fù)制到了 $TOMCAT/webapps/devworks 下,您就能用以下的步驟來測(cè)試 ReplaceTextFilter

    1. 編輯 $TOMCAT/wepapps/devworks/WEB-INF 目錄下的 web.xml 文件,以包含下列過濾器的定義及映射:

      <web-app>
                      <filter>
                      <filter-name>Replace Text Filter</filter-name>
                      <filter-class>com.ibm.devworks.filters.ReplaceTextFilter</filter-class>
                      <init-param>
                      <param-name>search</param-name>
                      <param-value>cannot</param-value>
                      </init-param>
                      <init-param>
                      <param-name>replace</param-name>
                      <param-value>must not</param-value>
                      </init-param>
                      </filter>
                      <filter-mapping>
                      <filter-name>Replace Text Filter</filter-name>
                      <url-pattern>/*</url-pattern>
                      </filter-mapping>
                      </web-app>
                      


    2. 重新啟動(dòng) Tomcat。

    3. 現(xiàn)在,請(qǐng)用下面的 URL 來訪問 index.html 頁面: http://<host name>:8080/devworks/index.html

    請(qǐng)注意, ReplaceTextFilter 是如何迅速地將 cannot變?yōu)?must not 的。想確信過濾使用了所有資源,您可以嘗試編寫輸出結(jié)果含有字符串 cannot的 JSP 頁或 servlet。





    回頁首


    過濾器鏈排列順序的重要性

    過濾器鏈?zhǔn)脚帕械捻樞蛉Q于 web.xml 描述信息內(nèi) <filter-mapping> 語句的順序。在大多數(shù)情況下,過濾器鏈?zhǔn)脚帕械捻樞蚴欠浅V匾摹R簿褪钦f,在應(yīng)用 A 過濾器前使用 B 過濾器與在使用 B 過濾器前使用 A 過濾器所得到的結(jié)果是完全不同的。如果一個(gè)應(yīng)用程序中使用了一個(gè)以上的過濾器,那么在寫入 <filter-mapping> 語句的時(shí)候要小心。

    我們能輕易地通過排列 web.xml 文件中 <filter-mapping> 的順序看到這一效果:



    清單 15. 過濾的順序 -- IE Filter 為先
    <web-app>
                <filter-mapping>
                <filter-name>IE Filter</filter-name>
                <url-pattern>/*</url-pattern>
                </filter-mapping>
                <filter-mapping>
                <filter-name>Replace Text Filter</filter-name>
                <url-pattern>/*</url-pattern>
                </filter-mapping>
                </web-app>
                

    現(xiàn)在,用 Internet Explorer 載入 index.html 頁。您能看到由于 IE Filter 處于過濾器鏈中的第一位,所以 Replace Text Filter 沒有機(jī)會(huì)執(zhí)行。因此,輸出的信息是 "Sorry, page cannot be displayed!"

    現(xiàn)在,將 <filter-mapping> 標(biāo)記的順序顛倒過來,變?yōu)椋?



    清單 16. 過濾的順序 -- Replace Text Filter 為先
    <web-app>
                <filter-mapping>
                <filter-name>Replace Text Filter</filter-name>
                <url-pattern>/*</url-pattern>
                </filter-mapping>
                <filter-mapping>
                <filter-name>IE Filter</filter-name>
                <url-pattern>/*</url-pattern>
                </filter-mapping>
                </web-app>
                

    再次用 Internet Explorer 載入 index.html 頁面。這次, Replace Text Filter 先執(zhí)行,將包裝的響應(yīng)對(duì)象提供給 IE Filter 。在 IE Filter 寫入了其定制的響應(yīng)后,專用的響應(yīng)對(duì)象在輸出結(jié)果到達(dá)最終用戶處以前完成轉(zhuǎn)換。故而,我們看到了這條信息:Sorry, page must not be displayed!





    回頁首


    在應(yīng)用程序中使用過濾器

    寫這篇文章的時(shí)候, Tomcat 4 正處于 beta 周期的后期,正式發(fā)行的日子已為期不遠(yuǎn)。主要的 J2EE 容器廠商都準(zhǔn)備好了將 Servlet 2.3 規(guī)范整合到其產(chǎn)品中去。對(duì)于 Servlet 2.3 過濾器如何工作有一個(gè)基本的了解有助于您在設(shè)計(jì)及編寫基于 J2EE 的應(yīng)用程序時(shí)往自己的工具庫中再加入一件多功能的工具。

    posted on 2007-07-10 09:36 冰封的愛 閱讀(116) 評(píng)論(0)  編輯  收藏 所屬分類: J2EE
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆檔案

    文章分類

    文章檔案

    相冊(cè)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲色大成网站www尤物| 免费黄色福利视频| 亚洲熟妇AV日韩熟妇在线| 精品国产香蕉伊思人在线在线亚洲一区二区| 精品国产污污免费网站aⅴ| 国产精品免费久久久久影院| 亚洲国产无线乱码在线观看| 亚洲精品视频观看| 久久亚洲国产成人亚| 国产亚洲一区区二区在线| 免费看国产一级片| 午夜成年女人毛片免费观看| 亚洲高清免费在线观看| 69av免费观看| 无码国产精品一区二区免费式芒果| 一级黄色免费毛片| 一级日本高清视频免费观看| 国产偷国产偷亚洲高清在线| 亚洲综合欧美色五月俺也去| 亚洲国产夜色在线观看| 亚洲成在人线电影天堂色| 亚洲嫩模在线观看| 亚洲成AV人片在线观看无| 久久精品国产69国产精品亚洲| 亚洲精品国产高清不卡在线| 国产免费av一区二区三区| 国产精品冒白浆免费视频 | 亚洲日本中文字幕天堂网| 免费永久在线观看黄网站| 暖暖免费高清日本一区二区三区| 成人免费视频88| 成熟女人牲交片免费观看视频| 歪歪漫画在线观看官网免费阅读| AV大片在线无码永久免费| 最近2019中文字幕mv免费看| 最近免费中文字幕大全| 日韩免费福利视频| 亚洲伦乱亚洲h视频| 中文亚洲AV片在线观看不卡| 亚洲性猛交XXXX| 亚洲视频在线视频|