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

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

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

    即使世界明天毀滅,我也要在今天種下我的葡萄樹。
    posts - 112, comments - 14, trackbacks - 0, articles - 11

    servlet和JSP過濾器Filter

    Posted on 2007-01-24 18:26 閱讀(177) 評論(0)  編輯  收藏
    或許,servlet API的2.3版本中最重要的一個新功能就是能夠為servlet和JSP頁面定義過濾器。過濾器提供了某些早期服務器所支持的非標準“servlet鏈接”的一種功能強大且標準的替代品。
    過濾器是一個程序,它先于與之相關的servlet或JSP頁面運行在服務器上。過濾器可附加到一個或多個servlet或JSP頁面上,并且可以檢查進入這些資源的請求信息。在這之后,過濾器可以作如下的選擇:
    l 以常規的方式調用資源(即,調用servlet或JSP頁面)。
    l 利用修改過的請求信息調用資源。
    l 調用資源,但在發送響應到客戶機前對其進行修改
    l 阻止該資源調用,代之以轉到其他的資源,返回一個特定的狀態代碼或生成替換輸出。
    過濾器提供了幾個重要好處。
    首先,它以一種模塊化的或可重用的方式封裝公共的行為。你有30個不同的serlvet或JSP頁面,需要壓縮它們的內容以減少下載時間嗎?沒問題:構造一個壓縮過濾器(參閱第11節),然后將它應用到30個資源上即可。
    其次,利用它能夠將高級訪問決策與表現代碼相分離。這對于JSP特別有價值,其中一般希望將幾乎整個頁面集中在表現上,而不是集中在業務邏輯上。例如,希望阻塞來自某些站點的訪問而不用修改各頁面(這些頁面受到訪問限制)嗎?沒問題:建立一個訪問限制過濾器(參閱第8節)并把它應用到想要限制訪問的頁面上即可。
    最后,過濾器使你能夠對許多不同的資源進行批量性的更改。你有許多現存資源,這些資源除了公司名要更改外其他的保持不變,能辦到么?沒問題:構造一個串替換過濾器(參閱第10節),只要合適就使用它。
    但要注意,過濾器只在與servlet規范2.3版兼容的服務器上有作用。如果你的Web應用需要支持舊版服務器,就不能使用過濾器。
    1. 建立基本過濾器
    建立一個過濾器涉及下列五個步驟:
    1)建立一個實現Filter接口的類。這個類需要三個方法,分別是:doFilter、init和destroy。doFilter方法包含主要的過濾代碼(見第2步),init方法建立設置操作,而destroy方法進行清楚。
    2)在doFilter方法中放入過濾行為。doFilter方法的第一個參數為ServletRequest對象。此對象給過濾器提供了對進入的信息(包括表單數據、cookie和HTTP請求頭)的完全訪問。第二個參數為ServletResponse,通常在簡單的過濾器中忽略此參數。最后一個參數為FilterChain,如下一步所述,此參數用來調用servlet或JSP頁。
    3)調用FilterChain對象的doFilter方法。Filter接口的doFilter方法取一個FilterChain對象作為它的一個參數。在調用此對象的doFilter方法時,激活下一個相關的過濾器。如果沒有另一個過濾器與servlet或JSP頁面關聯,則servlet或JSP頁面被激活。
    4)對相應的servlet和JSP頁面注冊過濾器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素。
    5)禁用激活器servlet。防止用戶利用缺省servlet URL繞過過濾器設置。
    1.1 建立一個實現Filter接口的類
    所有過濾器都必須實現javax.servlet.Filter。這個接口包含三個方法,分別為doFilter、init和destroy。
    l public void doFilter(ServletRequset request,
    ServletResponse response,
    FilterChain chain)
    thows ServletException, IOException
    每當調用一個過濾器(即,每次請求與此過濾器相關的servlet或JSP頁面)時,就執行其doFilter方法。正是這個方法包含了大部分過濾邏輯。
    第一個參數為與傳入請求有關的ServletRequest。對于簡單的過濾器,大多數過濾邏輯是基于這個對象的。如果處理HTTP請求,并且需要訪問諸如getHeader或getCookies等在ServletRequest中無法得到的方法,就要把此對象構造成HttpServletRequest。
    第二個參數為ServletResponse。除了在兩個情形下要使用它以外,通常忽略這個參數。首先,如果希望完全阻塞對相關servlet或JSP頁面的訪問。可調用response.getWriter并直接發送一個響應到客戶機。第7節給出詳細內容,第8節給出一個例子。其次,如果希望修改相關的servlet或JSP頁面的輸出,可把響應包含在一個收集所有發送到它的輸出的對象中。然后,在調用serlvet或JSP頁面后,過濾器可檢查輸出,如果合適就修改它,之后發送到客戶機。詳情請參閱第9節。
    DoFilter的最后一個參數為FilterChain對象。對此對象調用doFilter以激活與servlet或JSP頁面相關的下一個過濾器。如果沒有另一個相關的過濾器,則對doFilter的調用激活servlet或JSP本身。
    l public void init(FilterConfig config)
    thows ServletException
    init方法只在此過濾器第一次初始化時執行,不是每次調用過濾器都執行它。對于簡單的過濾器,可提供此方法的一個空體,但有兩個原因需要使用init。首先,FilterConfig對象提供對servlet環境及web.xml文件中指派的過濾器名的訪問。因此,普遍的辦法是利用init將FilterConfig對象存放在一個字段中,以便doFilter方法能夠訪問servlet環境或過濾器名。這種處理在第3節描述。其次,FilterConfig對象具有一個getInitParameter方法,它能夠訪問部署描述符文件(web.xml)中分配的過濾器初始化參數。初始化參數的使用在第5節中描述。
    l public void destroy( )
    此方法在利用一個給定的過濾器對象永久地終止服務器(如關閉服務器)時調用。大多數過濾器簡單地為此方法提供一個空體,不過,可利用它來完成諸如關閉過濾器使用的文件或數據庫連接池等清除任務。
    1.2 將過濾行為放入doFilter方法
    doFilter方法為大多數過濾器地關鍵部分。每當調用一個過濾器時,都要執行doFilter。對于大多數過濾器來說,doFilter執行的步驟是基于傳入的信息的。因此,可能要利用作為doFilter的第一個參數提供的ServletRequest。這個對象常常構造為HttpServletRequest類型,以提供對該類的更特殊方法的訪問。
    1.3 調用FilterChain對象的doFilter方法
    Filter接口的doFilter方法以一個FilterChain對象作為它的第三個參數。在調用該對象的doFilter方法時,激活下一個相關的過濾器。這個過程一般持續到鏈中最后一個過濾器為止。在最后一個過濾器調用其FilterChain對象的doFilter方法時,激活servlet或頁面自身。
    但是,鏈中的任意過濾器都可以通過不調用其FilterChain的doFilter方法中斷這個過程。在這樣的情況下,不再調用JSP頁面的serlvet,并且中斷此調用過程的過濾器負責將輸出提供給客戶機。詳情請參閱第7節。
    1.4 對適當的servlet和JSP頁面注冊過濾器
    部署描述符文件的2.3版本引入了兩個用于過濾器的元素,分別是:filter和filter-mapping。filter元素向系統注冊一個過濾對象,filter-mapping元素指定該過濾對象所應用的URL。
    1.filter元素
    filter元素位于部署描述符文件(web.xml)的前部,所有filter-mapping、servlet或servlet-mapping元素之前。filter元素具有如下六個可能的子元素:
    l icon 這是一個可選的元素,它聲明IDE能夠使用的一個圖象文件。
    l filter-name 這是一個必需的元素,它給過濾器分配一個選定的名字。
    l display-name 這是一個可選的元素,它給出IDE使用的短名稱。
    l description 這也是一個可選的元素,它給出IDE的信息,提供文本文檔。
    l filter-class 這是一個必需的元素,它指定過濾器實現類的完全限定名。
    l init-param 這是一個可選的元素,它定義可利用FilterConfig的getInitParameter方法讀取的初始化參數。單個過濾器元素可包含多個init-param元素。
    請注意,過濾是在serlvet規范2.3版中初次引入的。因此,web.xml文件必須使用DTD的2.3版本。下面介紹一個簡單的例子:
    <?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>MyFilter</filter-name>
    <filter-class>myPackage.FilterClass</filter-class>
    </filter>
    <!-- ... -->
    <filter-mapping>...</filter-mapping>
    </web-app>


    2.filter-mapping元素
    filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三個可能的子元素::
    l filter-name 這個必需的元素必須與用filter元素聲明時給予過濾器的名稱相匹配。
    l url-pattern 此元素聲明一個以斜杠(/)開始的模式,它指定過濾器應用的URL。所有filter-mapping元素中必須提供url-pattern或servlet-name。但不能對單個filter-mapping元素提供多個url-pattern元素項。如果希望過濾器適用于多個模式,可重復整個filter-mapping元素。
    l servlet-name 此元素給出一個名稱,此名稱必須與利用servlet元素給予servlet或JSP頁面的名稱相匹配。不能給單個filter-mapping元素提供多個servlet-name元素項。如果希望過濾器適合于多個servlet名,可重復這個filter-mapping元素。
    下面舉一個例子:
    <?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>MyFilter</filter-name>
    <filter-class>myPackage.FilterClass</filter-class>
    </filter>
    <!-- ... -->
    <filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/someDirectory/SomePage.jsp</url-pattern>
    </filter-mapping>
    </web-app>

    1.5 禁用激活器servlet
    在對資源應用過濾器時,可通過指定要應用過濾器的URL模式或servlet名來完成。如果提供servlet名,則此名稱必須與web.xml的servlet元素中給出的名稱相匹配。如果使用應用到一個serlvet的URL模式,則此模式必須與利用web.xml的元素servlet-mapping指定的模式相匹配。但是,多數服務器使用“激活器servlet”為servlet體統一個缺省的URL:http://host/WebAppPrefix/servlet/ServletName。需要保證用戶不利用這個URL訪問servlet(這樣會繞過過濾器設置)。
    例如,假如利用filter和filter-mapping指示名為SomeFilter的過濾器應用到名為SomeServlet的servlet,則如下:
    <filter>
    <filter-name>SomeFilter</filter-name>
    <filter-class>somePackage.SomeFilterClass</filter-class>
    </filter>
    <!-- ... -->
    <filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <servlet-name>SomeServlet</servlet-name>
    </filter-mapping>


    接著,用servlet和servlet-mapping規定URL http://host/webAppPrefix/Blah 應該調用SomeSerlvet,如下所示:

    <filter>
    <filter-name>SomeFilter</filter-name>
    <filter-class>somePackage.SomeFilterClass</filter-class>
    </filter>
    <!-- ... -->
    <filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <servlet-name>/Blah</servlet-name>
    </filter-mapping>


    現在,在客戶機使用URL http://host/webAppPrefix/Blah 時就會調用過濾器。過濾器不應用到
    http://host/webAppPrefix/servlet/SomePackage.SomeServletClass。
    盡管有關閉激活器的服務器專用方法。但是,可移植最強的方法時重新映射Web應用鐘的/servlet模式,這樣使所有包含此模式的請求被送到相同的servlet中。為了重新映射此模式,首先應該建立一個簡單的servlet,它打印一條錯誤消息,或重定向用戶到頂層頁。然后,使用servlet和servlet-mapping元素發送包含/servlet模式的請求到該servlet。程序清單9-1給出了一個簡短的例子。

    程序清單9-1 web.xml(重定向缺省servlet URL的摘錄)
    <?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>
    <!-- ... -->
    <servlet>
    <servlet-name>Error</servlet-name>
    <servlet-class>somePackage.ErrorServlet</servlet-class>
    </servlet>
    <!-- ... -->
    <servlet-mapping>
    <servlet-name>Error</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>
    <!-- ... -->
    </web-app>


    2. 樣例:報告過濾器
    趁熱打鐵,我們來試驗一個簡單的過濾器,只要調用相關的servlet或JSP頁面,它就打印一條消息到標準輸出。為了完成此任務,相應的過濾器必須具有下面的內容:
    1)實現Filter接口的一個類。這個類名為ReportFilter,如程序清單9-2所示。這個類對init和destroy方法提供空體。
    2)在doFilter方法中過濾行為。每當調用與這個過濾器相關的servlet或JSP頁面時,doFilter方法就生成一個打印輸出,此輸出列出請求主機和調用的URL。因為getRequestURL方法位于HttpServletRequest而不是ServletRequest中,所以把ServletRequest對象構造為HttpServletRequest類型。
    3)調用FilterChain的doFilter方法。在打印輸出報告后,過濾器調用FilterChain的doFilter方法激活servlet或JSP頁面(如果有的話,調用下一個過濾器)
    4)對Web應用主頁和顯示TodaysSpecialservlet進行注冊。首先,filter元素將名稱Reporter與類moreservlets.filters.ReportFilter相關聯。然后,filter-mapping元素使用/index.jsp的url-pattern將過濾器與主頁相關聯。最后,filter-mapping元素使用TodaysSpecial的servlet-name將過濾器與TodaysSpecialservlet(名稱TodaysSpecial是在servlet元素中聲明的)相關聯。參見程序清單9-3。
    5)禁用激活器servlet。首先,建立一個RedirectorServlet(見程序清單9-6),它把接收到的所有請求重定向到此Web應用的主頁。接著,利用servlet和servlet-mapping元素(參見程序清單9-3)指定所有以http://host/webAppPrefix/servlet/ 開始的URL都應該激活RedirectorServlet。
    給出這些設置后,每當客戶機請求此Web應用主頁(程序清單9-4)或TodaysSpecialservlet(程序清單9-5)時,都調用此過濾器。

    程序清單9-2 ReportFilter.java

    package moreservlets.filters;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.util.*; // For Date class

    /** Simple filter that prints a report on the standard output
    * each time an associated servlet or JSP page is accessed.
    */

    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() {}
    }



    程序清單9-3 web.xml(針對報告過濾器的摘錄)
    <?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>
    <!-- Register the name "Reporter" for ReportFilter. -->
    <filter>
    <filter-name>Reporter</filter-name>
    <filter-class>
    moreservlets.filters.ReportFilter
    </filter-class>
    </filter>
    <!-- ... -->
    <!-- Apply the Reporter filter to home page. -->
    <filter-mapping>
    <filter-name>Reporter</filter-name>
    <url-pattern>/index.jsp</url-pattern>
    </filter-mapping>
    <!-- Also apply the Reporter filter to the servlet named
    "TodaysSpecial".
    -->
    <filter-mapping>
    <filter-name>Reporter</filter-name>
    <servlet-name>TodaysSpecial</servlet-name>
    </filter-mapping>
    <!-- ... -->

    <!-- Give a name to the Today's Special servlet so that filters
    can be applied to it.
    -->
    <servlet>
    <servlet-name>TodaysSpecial</servlet-name>
    <servlet-class>
    moreservlets.TodaysSpecialServlet
    </servlet-class>
    </servlet>
    <!-- ... -->

    <!-- Make /TodaysSpecial invoke the servlet
    named TodaysSpecial (i.e., moreservlets.TodaysSpecial).
    -->
    <servlet-mapping>
    <servlet-name>TodaysSpecial</servlet-name>
    <url-pattern>/TodaysSpecial</url-pattern>
    </servlet-mapping>

    <!-- Turn off invoker. Send requests to index.jsp. -->
    <servlet-mapping>
    <servlet-name>Redirector</servlet-name>
    <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>
    <!-- ... -->
    </web-app>
    評論
    # re: servlet和JSP過濾器Filter
    程序清單9-4 index.jsp
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    <HEAD>
    <TITLE>Filters 'R' Us</TITLE>
    <LINK REL=STYLESHEET
    HREF="filter-styles.css"
    TYPE="text/css">
    </HEAD>
    <BODY>
    <CENTER>
    <TABLE BORDER=5>
    <TR><TH CLASS="TITLE">Filters 'R' Us</TABLE>
    <P>
    <TABLE>
    <TR>
    <TH><IMG SRC=http://www.host01.com/Get/jsp/00040005/"images/air-filter.jpg" ALT="Air Filter">
    <TH><IMG SRC=http://www.host01.com/Get/jsp/00040005/"images/coffee-filter.gif" ALT="Coffee Filter">
    <TH><IMG SRC=http://www.host01.com/Get/jsp/00040005/"images/pump-filter.jpg" ALT="Pump Filter">
    </TR>
    </TABLE>

    <H3>We specialize in the following:</H3>
    <UL>
    <LI>Air filters
    <LI>Coffee filters
    <LI>Pump filters
    <LI>Camera lens filters
    <LI>Image filters for Adobe Photoshop
    <LI>Web content filters
    <LI>Kalman filters
    <LI>Servlet and JSP filters
    </UL>
    Check out <A HREF="TodaysSpecial">Today's Special</A>.
    </CENTER>
    </BODY>
    </HTML>


    程序清單9-5 TodaysSpecialServlet.java
    package moreservlets;

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

    /** Sample servlet used to test the simple filters. */

    public class TodaysSpecialServlet extends HttpServlet {
    private String title, picture;

    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    updateSpecials();
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String docType =
    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
    "Transitional//EN\">\n";
    out.println
    (docType +
    "<HTML>\n" +
    "<HEAD><TITLE>Today's Special</TITLE></HEAD>\n" +
    "<BODY BGCOLOR=\"WHITE\">\n" +
    "<CENTER>\n" +
    "<H1>Today's Special: " + title + "s!</H1>\n" +
    "<IMG SRC=\"images/" + picture + "\"\n" +
    " ALT=\"" + title + "\">\n" +
    "<BR CLEAR=\"ALL\">\n" +
    "Special deal: for only twice the price, you can\n" +
    "<I>buy one, get one free!</I>.\n" +
    "</BODY></HTML>");
    }

    // Rotate among the three available filter images.

    private void updateSpecials() {
    double num = Math.random();
    if (num < 0.333) {
    title = "Air Filter";
    picture = "air-filter.jpg";
    } else if (num < 0.666) {
    title = "Coffee Filter";
    picture = "coffee-filter.gif";
    } else {
    title = "Pump Filter";
    picture = "pump-filter.jpg";
    }
    }
    }


    程序清單9-6 RedirectorServlet.java
    package moreservlets;

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

    /** Servlet that simply redirects users to the
    * Web application home page. Registered with the
    * default servlet URL to prevent clients from
    * using http://host/webAppPrefix/servlet/ServletName
    * to bypass filters or security settings that
    * are associated with custom URLs.
    */

    public class RedirectorServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    response.sendRedirect(request.getContextPath());
    }

    public void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    doGet(request, response);
    }
    }


    3. 從過濾器中訪問servlet環境
    前一節的ReportFilter只要調用指定的servlet或JSP頁面,就在標準輸出上打印一個報告。當你在自己的桌面系統上運行一個服務器時,一般會用一個顯示標準輸出的窗口,在開發過程中,標準輸出上的報告很好用。但在部署過程中,不可能訪問這個窗口。因此,一種自然的改進是將報告寫入servlet日志文件寫到標準輸出。
    Servlet API提供了兩個log方法:一個取一個簡單的String而另一個取一個String和一個Throwable。這兩個方法都可以從GenericServlet或ServletContext類中使用。關于這兩個方法所用的日志文件的準確位置,請查看相關服務器的幫助文檔。問題是doFilter方法在與其相關的serlvet或JSP頁面之前執行。因此,你不能訪問該servlet的實例,從而不能調用從GenericServlet繼承的log方法。此外,API沒有體統從doFilter方法中訪問ServletContext的簡單方法。可以訪問ServletContext的方法并且與過濾器相關的唯一類是FilterConfig,訪問ServletContext的方法為getServletContext。FilterConfig對象被傳輸給init方法,但不會自動存放到doFilter可使用的某個位置。
    因此,你必須自己存放FilterConfig??山⒁粋€FilterConfig類型的字段,然后重載init,將它的參數分配給該字段。因為一般只使用FilterConfig對象來訪問ServletContext和過濾器名,所以可以存放該ServletContext和名稱在字段中。相面舉一個例子:
    public class SomeFilter implements Filter {
    protected FilterConfig config;
    private ServletContext context;
    private String filterName;
    public void init(FilterConfig config)
    throws ServletException {
    this.config = config; // In case it is needed by subclass.
    context = config.getServletContext();
    filterName = config.getFilterName();
    }

    // doFilter and destroy methods...
    }
    4. 例子:日志記錄過濾器
    我們來更新ReportFilter(程序清單9-2),以便消息進入日志文件而不是標準輸出。為了完成這個任務,過濾器應該具有下列內容:
    1)實現Filter接口的一個類。這個類名為LogFilter,如程序清單9-7所示。這個類的init方法在過濾器的字段中存放FilterConfig、ServletContext和過濾器名。它對destory方法提供一個空體。
    2)在doFilter方法中過濾行為。這個行為和ReportFilter的行為之間有兩點不同:報告放于日志文件中而不是標準輸出中,報告包括過濾器的名稱。
    3)調用FilterChain的doFilter方法。在打印出報告后,此過濾器調用FilterChain的doFilter方法激活鏈中的下一個過濾器(如果沒有更多的過濾器,則激活servlet或JSP頁面)。
    4)對所有URL進行注冊。首先,filter元素將名稱LogFilter與類moreservlets.filters.LogFilter相關聯。接著,filter-mapping元素使用值為/*的url-pattern將此過濾器與Web應用中所有URL相關聯。參看程序清單9-8。
    5)禁用激活servlet。這個操作已經在第2節介紹過,這里就不再重復了。
    當這個Web應用部署在一個外部服務器上且附加了日志記錄過濾器后,客戶機對此Web應用主頁的請求將在日志文件中產生一個項,如:“audits.irs.gov tired to acces http://www.filtersrus.com/filters/index.jsp on Fri Oct 26 15:16:15 EDT 2001.(Reported by Logger.)”。

    程序清單9-7 LogFilter.java
    package moreservlets.filters;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.util.*; // For Date class

    /** Simple filter that prints a report in the log file
    * whenever the associated servlets or JSP pages
    * are accessed.
    */

    public class LogFilter implements Filter {
    protected FilterConfig config;
    private ServletContext context;
    private String filterName;
    public void doFilter(ServletRequest request,
    ServletResponse response,
    FilterChain chain)
    throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest)request;
    context.log(req.getRemoteHost() +
    " tried to access " +
    req.getRequestURL() +
    " on " + new Date() + ". " +
    "(Reported by " + filterName + ".)");
    chain.doFilter(request,response);
    }

    public void init(FilterConfig config)
    throws ServletException {
    this.config = config; // In case it is needed by subclass.
    context = config.getServletContext();
    filterName = config.getFilterName();
    }

    public void destroy() {}

    }


    程序清單9-8 web.xml(針對日志記錄過濾器的摘錄)
    <?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>
    <!-- ... -->

    <!-- Register the name "Logger" for LogFilter. -->
    <filter>
    <filter-name>Logger</filter-name>
    <filter-class>
    moreservlets.filters.LogFilter
    </filter-class>
    </filter>
    <!-- ... -->

    <!-- Apply the Logger filter to all servlets and
    JSP pages.
    -->
    <filter-mapping>
    <filter-name>Logger</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- ... -->
    </web-app>


    5. 利用過濾器的初始化參數
    對于servlet和JSP頁面,可通過提供初始化參數定制初始化行為。這個功能之所以游泳的原因在于有三組不同的人員可能希望定制servlet或JSP頁面的行為,這三組人員分別為:
    1)開發人員——他們通過更改serlvet或JSP頁面的代碼定制相應的行為。
    2)最終用戶——他們通過在HTML表單中輸入值來定制相應的行為。
    3)部署人員——這是提供初始化參數服務的一組人員。這組人員是那些獲得現存Web應用(或個別的servlet或JSP頁面)并在一個定制環境環境中部署它們的人員。他們不一定是開發人員,因此期望他們修改servlet和JSP代碼是不現實的。但由于過濾器在它們所附加的servlet或JSP頁面之前執行,最終用戶一般不能定制過濾器的行為,這種能力仍然很有用。定制過濾器的行為用如下步驟完成:
    1)定義初始化參數。使用web.xml中的filter的init-param子元素以及param-nam和param-value子元素,如下所示。

    <filter>
    <filter-name>SomeFilter</filter-name>
    <filter-class>somePackage.SomeFilterClass</filter-class>
    <init-param>
    <param-name>param1</param-name>
    <param-value>value1</param-value>
    </init-param>
    <init-param>
    <param-name>param2</param-name>
    <param-value>value2</param-value>
    </init-param>
    </filter>

    2)讀初始化參數。從過濾器的inti方法中調用FilterConfig的getInitParameter方法。如下所示。

    public void init(FilterConfig config)
    throws ServletException {
    String val1 = config.getInitParameter("param1");
    String val2 = config.getInitParameter("param2");
    ...
    }

    3)分析初始化參數。就像servlet和JSP的初始化參數一樣,每個過濾器的初始化都是String類型的。因此,如果想要其他類型的值,必須對它進行轉換。例如,可用Integer.parseInt將String“7”轉換為int 7。在分析時,別忘了檢查缺少的和不良的數據。缺少初始化參數將導致從getInitParameter返回null。即使這些參數存在,也一個來考慮到部署人員不正確地對其值進行格式化的可能性。例如,在轉換String類型的值為int類型的值時,應該將Integer.parseInt調用封在try/catch中,這個塊捕捉NumberFormatException。這種辦法徹底地處理了null和格式化不正確的值。
    6. 例子:訪問時的過濾器
    第4節的LogFilter,每當相關的servlet或JSP頁面被訪問時,就在日志文件中打印一個項。假如想修改它,使它只注意不尋常時刻出現的訪問。因為“不尋?!币暰唧w情況而定,servlet應該提供不尋常時間范圍的缺省值,并允許部署人員通過初始化參數來重載這些值。為了完成這種功能,相應的過濾器應該具有下面的內容:
    1)實現Filter接口的一個類。這個類名為LateAccessFilter,如程序清單9-9所示。這個類的init方法讀取startTime和endTime初始化參數。它嘗試作為init分析這些值,如果這些參數為null或未格式化為整數,這使用缺省值。然后,它將開始和結束事件、FilterConfig、ServletContext以及過濾器名存入過濾器的字段。最后,LateAccessFilter對destroy方法提供一個空體。
    2)在doFilter方法中過濾行為。這個方法查找當前事件,看它問是否在開始時間和結束事件給出的范圍內,如果是,打印一個日志項。
    3)調用FilterChain的doFilter方法。在打印出報告后,此過濾器調用FilterChain的doFilter方法激活鏈中的下一個過濾器(如果沒有更多的過濾器,則激活servlet或JSP頁面)。
    4)對Web應用主頁進行注冊;定義初始化參數。首先,filter元素將名稱LateAccessFilter與類moreservlets.filters.LateAccessFilter相關聯。filter元素還包含兩個init-param子元素:一個定義startTime參數,另一個定義endTime參數。因為將要訪問filterRus主頁的人是程序員,考慮反常的時間范圍為上午2:00到10:00之間。最后,filter-mapping元素使用值為/index.jsp的ulr-pattern子元素,將此過濾器與Web應用主頁相關聯。參看程序清單9-10。
    5)己用激活器serlvet。這個已經在第2節介紹過,不再重復。
    當這個Web應用部署在一個外部服務器上且附加了日志記錄過濾器后,客戶機對此Web應用主頁的請求將在日志文件中產生一個項,如:“WARNING: hacker6.filtersrus.com accessed http://www.filtersrus.com/filters/index.jsp on Oct 30,2001 9:22:09 AM.”。

    程序清單9-9 LateAccessFilter.java
    package moreservlets.filters;

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

    /** Filter that keeps track of accesses that occur
    * at unusual hours.
    */
    public class LateAccessFilter implements Filter {
    private FilterConfig config;
    private ServletContext context;
    private int startTime, endTime;
    private DateFormat formatter;
    public void doFilter(ServletRequest request,
    ServletResponse response,
    FilterChain chain)
    throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest)request;
    GregorianCalendar calendar = new GregorianCalendar();
    int currentTime = calendar.get(calendar.HOUR_OF_DAY);
    if (isUnusualTime(currentTime, startTime, endTime)) {
    context.log("WARNING: " +
    req.getRemoteHost() +
    " accessed " +
    req.getRequestURL() +
    " on " +
    formatter.format(calendar.getTime()));
    }
    chain.doFilter(request,response);
    }

    public void init(FilterConfig config)
    throws ServletException {
    this.config = config;
    context = config.getServletContext();
    formatter =
    DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
    DateFormat.MEDIUM);
    try {
    startTime =
    Integer.parseInt(config.getInitParameter("startTime"));
    endTime =
    Integer.parseInt(config.getInitParameter("endTime"));
    } catch(NumberFormatException nfe) { // Malformed or null
    // Default: access at or after 10 p.m. but before 6 a.m.
    // is considered unusual.
    startTime = 22; // 10:00 p.m.
    endTime = 6; // 6:00 a.m.
    }
    }

    public void destroy() {}

    // Is the current time between the start and end
    // times that are marked as abnormal access times?

    private boolean isUnusualTime(int currentTime,
    int startTime,
    int endTime) {
    // If the start time is less than the end time (i.e.,
    // they are two times on the same day), then the
    // current time is considered unusual if it is
    // between the start and end times.
    if (startTime < endTime) {
    return((currentTime >= startTime) &&
    (currentTime < endTime));
    }
    // If the start time is greater than or equal to the
    // end time (i.e., the start time is on one day and
    // the end time is on the next day), then the current
    // time is considered unusual if it is NOT between
    // the end and start times.
    else {
    return(!isUnusualTime(currentTime, endTime, startTime));
    }
    }
    }


    程序清單9-10 web.xml(針對訪問時過濾器的摘錄)
    <?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>
    <!-- ... -->

    <!-- Register the name "LateAccessFilter" for
    moreservlets.filter.LateAccessFilter.
    Supply two initialization parameters:
    startTime and endTime.
    -->
    <filter>
    <filter-name>LateAccessFilter</filter-name>
    <filter-class>
    moreservlets.filters.LateAccessFilter
    </filter-class>
    <init-param>
    <param-name>startTime</param-name>
    <param-value>2</param-value>
    </init-param>
    <init-param>
    <param-name>endTime</param-name>
    <param-value>10</param-value>
    </init-param>
    </filter>
    <!-- ... -->

    <!-- Apply LateAccessFilter to the home page. -->
    <filter-mapping>
    <filter-name>LateAccessFilter</filter-name>
    <url-pattern>/index.jsp</url-pattern>
    </filter-mapping>

    <!-- ... -->
    </web-app>

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 18禁男女爽爽爽午夜网站免费| 久久精品亚洲综合专区| 无码av免费一区二区三区试看| 处破女第一次亚洲18分钟| 亚洲第一页在线播放| 亚洲国产婷婷六月丁香| 亚洲日韩在线中文字幕第一页 | 亚洲中文字幕视频国产| 好男人www免费高清视频在线| 久章草在线精品视频免费观看| 一区二区三区在线观看免费 | 蜜桃精品免费久久久久影院| **一级一级毛片免费观看| 182tv免费视频在线观看| 成人免费网站久久久| 亚洲av成人一区二区三区观看在线 | 亚洲高清一区二区三区电影| 亚洲伊人久久大香线蕉在观| 777亚洲精品乱码久久久久久 | a级毛片免费观看在线| 黄网站色视频免费看无下截| 亚洲成av人在线观看网站| 中文字幕精品三区无码亚洲| 亚洲五月丁香综合视频| 亚洲成综合人影院在院播放| 亚洲成在人线中文字幕| 久久亚洲AV成人无码电影| 亚洲综合一区二区精品导航| 亚洲国产综合专区在线电影| 亚洲AV日韩AV天堂久久| 久久久久亚洲精品成人网小说 | 日本免费久久久久久久网站| 久久aa毛片免费播放嗯啊| 久久99精品视免费看| 毛片免费全部播放无码| 久久福利资源网站免费看| 无码一区二区三区AV免费| 巨胸喷奶水视频www网免费| 香蕉高清免费永久在线视频| 免费h成人黄漫画嘿咻破解版| 丁香亚洲综合五月天婷婷|