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配置

[html] view plaincopy
  1. <!-- 編碼過濾器 -->  
  2.     <filter>  
  3.         <filter-name>setCharacterEncoding</filter-name>  
  4.         <filter-class>com.company.strutstudy.web.servletstudy.filter.EncodingFilter</filter-class>  
  5.         <init-param>  
  6.             <param-name>encoding</param-name>  
  7.             <param-value>utf-8</param-value>  
  8.         </init-param>  
  9.     </filter>  
  10.     <filter-mapping>  
  11.         <filter-name>setCharacterEncoding</filter-name>  
  12.         <url-pattern>/*</url-pattern>  
  13.     </filter-mapping>  
  14.    
  15. <!-- 請求url日誌記錄過濾器 -->  
  16.     <filter>  
  17.         <filter-name>logfilter</filter-name>  
  18.         <filter-class>com.company.strutstudy.web.servletstudy.filter.LogFilter</filter-class>  
  19.     </filter>  
  20.     <filter-mapping>  
  21.         <filter-name>logfilter</filter-name>  
  22.         <url-pattern>/*</url-pattern>  
  23.     </filter-mapping>  

編碼攔截器:

[java] view plaincopy
  1. public class EncodingFilter implements Filter {  
  2.     private String encoding;  
  3.     private Map<String, String> params = new HashMap<String, String>();  
  4.     // 項目結束時就已經進行銷燬  
  5.     public void destroy() {  
  6.         System.out.println("end do the encoding filter!");  
  7.         params=null;  
  8.         encoding=null;  
  9.     }  
  10.     public void doFilter(ServletRequest req, ServletResponse resp,  
  11.             FilterChain chain) throws IOException, ServletException {  
  12.         //UtilTimerStack.push("EncodingFilter_doFilter:");  
  13.         System.out.println("before encoding " + encoding + " filter!");  
  14.         req.setCharacterEncoding(encoding);  
  15.         // resp.setCharacterEncoding(encoding);  
  16.         // resp.setContentType("text/html;charset="+encoding);  
  17.         chain.doFilter(req, resp);        
  18.         System.out.println("after encoding " + encoding + " filter!");  
  19.         System.err.println("----------------------------------------");  
  20.         //UtilTimerStack.pop("EncodingFilter_doFilter:");  
  21.     }  
  22.    
  23.     // 項目啓動時就已經進行讀取  
  24.     public void init(FilterConfig config) throws ServletException {  
  25.         System.out.println("begin do the encoding filter!");  
  26.         encoding = config.getInitParameter("encoding");  
  27.         for (Enumeration e = config.getInitParameterNames(); e  
  28.                 .hasMoreElements();) {  
  29.             String name = (String) e.nextElement();  
  30.             String value = config.getInitParameter(name);  
  31.             params.put(name, value);  
  32.         }  
  33.     }  
  34.  }  
日誌攔截器:
[java] view plaincopy
  1. public class LogFilter implements Filter {  
  2.     FilterConfig config;  
  3.    
  4.     public void destroy() {  
  5.         this.config = null;  
  6.     }  
  7.    
  8.     public void doFilter(ServletRequest req, ServletResponse res,  
  9.             FilterChain chain) throws IOException, ServletException {  
  10.         // 獲取ServletContext 對象,用於記錄日誌  
  11.         ServletContext context = this.config.getServletContext();  
  12.         //long before = System.currentTimeMillis();  
  13.         System.out.println("before the log filter!");  
  14.         //context.log("開始過濾");  
  15.         // 將請求轉換成HttpServletRequest 請求  
  16.         HttpServletRequest hreq = (HttpServletRequest) req;  
  17.         // 記錄日誌  
  18.         System.out.println("Log Filter已經截獲到用戶的請求的地址:"+hreq.getServletPath() );  
  19.         //context.log("Filter已經截獲到用戶的請求的地址: " + hreq.getServletPath());  
  20.         try {  
  21.             // Filter 只是鏈式處理,請求依然轉發到目的地址。  
  22.             chain.doFilter(req, res);  
  23.         } catch (Exception e) {  
  24.             e.printStackTrace();  
  25.         }  
  26.         System.out.println("after the log filter!");  
  27.         //long after = System.currentTimeMillis();  
  28.         // 記錄日誌  
  29.         //context.log("過濾結束");  
  30.         // 再次記錄日誌  
  31.         //context.log(" 請求被定位到" + ((HttpServletRequest) req).getRequestURI()  
  32.         //      + "所花的時間爲: " + (after - before));  
  33.     }  
  34.    
  35.     public void init(FilterConfig config) throws ServletException {  
  36.         System.out.println("begin do the log filter!");  
  37.         this.config = config;  
  38.     }  
  39.    
  40.  }  
HelloServlet類:
[java] view plaincopy
  1. public class HelloWorldServlet extends HttpServlet{  
  2.    
  3.     /** 
  4.      * 查看httpservlet實現的service一看便知,起到了一個controll控制器的作用(轉向的) 
  5.      * 之後便是跳轉至我們熟悉的doget,dopost等方法中  
  6.      */  
  7.     @Override  
  8.     protected void service(HttpServletRequest req, HttpServletResponse resp)  
  9.             throws ServletException, IOException {  
  10.         System.out.println("doservice..."+this.getInitParameter("encoding"));  
  11.           
  12.         super.service(req, resp);  
  13.     }  
  14.    
  15.     @Override  
  16.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  17.             throws ServletException, IOException {  
  18.         System.out.println("doget...");  
  19.         doPost(req, resp);  
  20.     }  
  21.    
  22.     @Override  
  23.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  24.             throws ServletException, IOException {  
  25.         System.out.println("dopost...");  
  26.     }  
  27.       
  28.       
  29.    
  30.  }  
結果:

[plain] view plaincopy
  1. before encoding utf-8 filter!  
  2.   before the log filter!  
  3.   Log Filter已經截獲到用戶的請求的地址:/hello  
  4.   doservice...UTF-8  
  5.   doget...  
  6.   dopost...  
  7.   after the log filter!  
  8.   after encoding utf-8 filter!  
  9.   ----------------------------------------  

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