過濾器和攔截器的區別

項目中會用到過濾器(Filter)和攔截器(Interceptor)。

首先看一下這兩者之間的包含關係:

如上圖所示,二者之間的觸發時機不同:

執行順序爲: 過濾前-攔截前-action執行-攔截後-過濾後

 

1.    過濾器:

過濾器是JavaEE標準,基於函數回調。主要對客戶請求做預處理。

過濾器的觸發是在請求進入容器後,且請求進入servlet之前進行預處理的。所以請求結束返回是在servlet處理完之後,返給前端之前。

由於觸發是在容器之後,servlet之前,所以filter的傳參是servlet而不是 httpservlet

@Component
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        filterChain.doFilter(request, response);
    }
    
    @Override
    public void destroy() {
    }

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

2.    攔截器:

  攔截器是spring容器的,由spring支持。是AOP的一種實現策略。

public class MyInterceptor implements HandlerInterceptor {
   
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

preHandle()是在過濾器 filterChain.doFilter(request, response);方法的前一步執行,

postHandle()是在方法請求之間 進行,

afterCompletion()方法是在過濾器返回給前端前一步執行,即filterChain.doFilter(request, response)方法之後執行,

springmvc的機制是由同一個Servlet分發請求給不同的Controller,這一步其實是在Servlet的service方法中執行的。

 

主要區別:

1.  攔截器基於Java反射機制, 過濾器基於函數回調,是javaEE的標準。

2.  攔截器不依賴於servlet,過濾器不依賴於servlet。

3.  攔截器只對action請求起作用,過濾器對幾乎所有請求起作用。

4.  攔截器可以訪問action上下文,值棧裏的對象, 過濾器不能訪問。

5.  在action的生命週期中,攔截器可以被多次調用,過濾器只能容器初始化時調用一次。

6.  攔截器可以獲取IOC容器的各個bean,即可以在攔截器注入service層,調用邏輯層代碼, 過濾器不行。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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