Servlet中的過濾器Filter詳解

web.xml中元素執行的順序listener->filter->struts攔截器->servlet。

1.過濾器的概念

Java中的Filter 並不是一個標準的Servlet ,它不能處理用戶請求,也不能對客戶端生成響應。 主要用於對HttpServletRequest 進行預處理,也可以對HttpServletResponse 進行後處理,是個典型的處理鏈。

優點:過濾鏈的好處是,執行過程中任何時候都可以打斷,只要不執行chain.doFilter()就不會再執行後面的過濾器和請求的內容。而在實際使用時,就要特別注意過濾鏈的執行順序問題

2.過濾器的作用描述

  • 在HttpServletRequest 到達Servlet 之前,攔截客戶的HttpServletRequest 。 
  •   根據需要檢查HttpServletRequest ,也可以修改HttpServletRequest 頭和數據。 
  •   在HttpServletResponse 到達客戶端之前,攔截HttpServletResponse 。 
  • 根據需要檢查HttpServletResponse ,可以修改HttpServletResponse 頭和數據。

3.過濾器的執行流程


4.Filter接口

1.如何驅動

在 web 應用程序啓動時,web 服務器將根據 web.xml 文件中的配置信息來創建每個註冊的 Filter 實例對象,並將其保存在服務器的內存中

2.方法介紹

    • init()  Init 方法在 Filter 生命週期中僅執行一次,web 容器在調用 init 方法時
    • destory()  在Web容器卸載 Filter 對象之前被調用。該方法在Filter的生命週期中僅執行一次。在這個方法中,可以釋放過濾器使用的資源。
    • doFilter() Filter 鏈的執行 

5.FilterChain接口

1.如何實例化

代表當前 Filter 鏈的對象。由容器實現,容器將其實例作爲參數傳入過濾器對象的doFilter()方法中

2.作用

調用過濾器鏈中的下一個過濾器

filter實例:

web.xml配置

<!-- 編碼過濾器 -->  
    <filter>  
        <filter-name>setCharacterEncoding</filter-name>  
        <filter-class>com.company.strutstudy.web.servletstudy.filter.EncodingFilter</filter-class>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>utf-8</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>setCharacterEncoding</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
   
<!-- 請求url日誌記錄過濾器 -->  
    <filter>  
        <filter-name>logfilter</filter-name>  
        <filter-class>com.company.strutstudy.web.servletstudy.filter.LogFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>logfilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
編碼攔截器:

public class EncodingFilter implements Filter {  
    private String encoding;  
    private Map<String, String> params = new HashMap<String, String>();  
    // 項目結束時就已經進行銷燬  
    public void destroy() {  
        System.out.println("end do the encoding filter!");  
        params=null;  
        encoding=null;  
    }  
    public void doFilter(ServletRequest req, ServletResponse resp,  
            FilterChain chain) throws IOException, ServletException {  
        //UtilTimerStack.push("EncodingFilter_doFilter:");  
        System.out.println("before encoding " + encoding + " filter!");  
        req.setCharacterEncoding(encoding);  
        // resp.setCharacterEncoding(encoding);  
        // resp.setContentType("text/html;charset="+encoding);  
        chain.doFilter(req, resp);        
        System.out.println("after encoding " + encoding + " filter!");  
        System.err.println("----------------------------------------");  
        //UtilTimerStack.pop("EncodingFilter_doFilter:");  
    }  
   
    // 項目啓動時就已經進行讀取  
    public void init(FilterConfig config) throws ServletException {  
        System.out.println("begin do the encoding filter!");  
        encoding = config.getInitParameter("encoding");  
        for (Enumeration e = config.getInitParameterNames(); e  
                .hasMoreElements();) {  
            String name = (String) e.nextElement();  
            String value = config.getInitParameter(name);  
            params.put(name, value);  
        }  
    }  
 }  
日誌攔截器:
public class LogFilter implements Filter {  
    FilterConfig config;  
   
    public void destroy() {  
        this.config = null;  
    }  
   
    public void doFilter(ServletRequest req, ServletResponse res,  
            FilterChain chain) throws IOException, ServletException {  
        // 獲取ServletContext 對象,用於記錄日誌  
        ServletContext context = this.config.getServletContext();  
        //long before = System.currentTimeMillis();  
        System.out.println("before the log filter!");  
        //context.log("開始過濾");  
        // 將請求轉換成HttpServletRequest 請求  
        HttpServletRequest hreq = (HttpServletRequest) req;  
        // 記錄日誌  
        System.out.println("Log Filter已經截獲到用戶的請求的地址:"+hreq.getServletPath() );  
        //context.log("Filter已經截獲到用戶的請求的地址: " + hreq.getServletPath());  
        try {  
            // Filter 只是鏈式處理,請求依然轉發到目的地址。  
            chain.doFilter(req, res);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("after the log filter!");  
        //long after = System.currentTimeMillis();  
        // 記錄日誌  
        //context.log("過濾結束");  
        // 再次記錄日誌  
        //context.log(" 請求被定位到" + ((HttpServletRequest) req).getRequestURI()  
        //      + "所花的時間爲: " + (after - before));  
    }  
   
    public void init(FilterConfig config) throws ServletException {  
        System.out.println("begin do the log filter!");  
        this.config = config;  
    }  
   
 }  
HelloServlet類:

public class HelloWorldServlet extends HttpServlet{  
   
    /** 
     * 查看httpservlet實現的service一看便知,起到了一個controll控制器的作用(轉向的) 
     * 之後便是跳轉至我們熟悉的doget,dopost等方法中  
     */  
    @Override  
    protected void service(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        System.out.println("doservice..."+this.getInitParameter("encoding"));  
          
        super.service(req, resp);  
    }  
   
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        System.out.println("doget...");  
        doPost(req, resp);  
    }  
   
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        System.out.println("dopost...");  
    }  
 }  
結果: 

before encoding utf-8 filter!  
  before the log filter!  
  Log Filter已經截獲到用戶的請求的地址:/hello  
  doservice...UTF-8  
  doget...  
  dopost...  
  after the log filter!  
  after encoding utf-8 filter!  
  ----------------------------------------  

總結:

1.過濾器執行流程

2.常用過濾器



<pre name="code" class="plain"><pre></pre><pre name="code" class="plain"></pre><pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
<pre></pre>  
  
</pre>




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章