過濾器&監聽器&攔截器

1、攔截器與過濾器的區別

Spring的攔截器與Servlet的過濾器有相似之處,比如二者都是AOP編程思想的體現,都能實現權限檢查,日誌記錄等。不同的是:
 1. 使用範圍不同:過濾器Filter是Servlet規範規定的,只能用於Web程序中。而攔截器Interceptor既可以用於Web程序中,也可以用於Application、Swing程序中。

 2. 規範不同:Filter是在Servlet規範中定義的,是Servlet容器支持的。而攔截器是Spring容器內的,是Spring框架支持的。

 3. 使用的資源不同: 同其他的代碼塊一樣,攔截器也是一個Spring的組件,歸Spring管理,配置在Spring文件中,因此能使用Spring裏的任何資源、對象,例如Service對象、數據源、事務管理等,通過 IOC注入到攔截器即可;而Filter則不能。

 4. 深度不同:Filter只在Servlet前後起作用。而攔截器能夠深入到方法前後、異常拋出前後等,因此攔截器的使用具有更大的彈性,所以在Spring構架的程序中,要優先使用攔截器。

過濾器和攔截器的區別:(另一種說法)
  ①攔截器是基於java的反射機制的,而過濾器是基於函數回調。
  ②攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
  ③攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。
  ④攔截器可以訪問action上下文、值棧裏的對象,而過濾器不能訪問。
  ⑤在action的生命週期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次。
  ⑥攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器裏注入一個service,可以調用業務邏輯。
  
過濾器與攔截器執行順序:轉載原文

以下是過濾器示例代碼

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("過濾器之前...");
        chain.doFilter(request, response);
        System.out.println("過濾器之後...");
    }

  chain.doFilter(request, response);這個方法的調用作爲分水嶺。事實上調用Servlet的doService()方法是在chain.doFilter(request, response);這個方法中進行的。

以下是攔截器示例代碼

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("攔截器之前···");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("攔截器業務邏輯···");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("攔截器之後···");
    }

  1). preHandle()這個方法是在過濾器的chain.doFilter(request, response)方法的前一步執行,也就是在 System.out.println("過濾器之前...")chain.doFilter(request, response)之間執行。
  2). postHandle()方法是在執行完Controller邏輯,在return ModelAndView之前進行,可以操控Controller的ModelAndView內容。
  3). afterCompletion()方法是在過濾器返回給前端前一步執行,也就是在chain.doFilter(request, response)System.out.println("過濾器之後...")之間執行。
執行順序圖

  總結: SpringMVC的機制是由同一個Servlet來分發請求,吧請求給不同的Controller,其實這一步是在Servlet的service()方法中執行的。所以過濾器、攔截器、service()方法,dispatc()方法的執行順序應該是如上圖:其實非常好測試,自己寫一個過濾器,一個攔截器,然後在這些方法中都加個斷點,一路F8下去就得出了結論。

監聽器轉載出處
   監聽器與以上兩種區別較大,這裏單獨介紹
監聽器用於監聽web應用中某些對象、信息的創建、銷燬、增加,修改,刪除等動作的發生,然後作出相應的響應處理。當範圍對象的狀態發生變化的時候,服務器自動調用監聽器對象中的方法。常用於統計在線人數和在線用戶,系統加載時進行信息初始化,統計網站的訪問量等等。
分類:

按監聽的對象劃分

  • ServletContext對象監聽器:用於監聽應用程序環境對象事件
  • HttpSession對象監聽器:用於監聽用戶會話對象事件
  • ServletRequest對象監聽器:用於監聽請求消息對象事件

按監聽的事件劃分

  • 對象自身的創建和銷燬的監聽器
  • 對象中屬性的創建和消除的監聽器
  • session中的某個對象的狀態變化的監聽器

示例:統計在線人數

public class onLineCount implements HttpSessionListener {

    public int count=0;//記錄session的數量
    public void sessionCreated(HttpSessionEvent arg0) {//監聽session的創建
        count++;
        arg0.getSession().getServletContext().setAttribute("Count", count);

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) {//監聽session的撤銷
        count--;
        arg0.getSession().getServletContext().setAttribute("Count", count);
    }

}

在web.xml中的配置爲:

<listener>
     <listener-class>com.ygj.control.onLineCount</listener-class>
  </listener>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章