filter和interceptor的區別


前言

最近在面試的時候,被問到了這個問題,覺得答得不是很好,在此進行整理和記錄,供自己學習,也希望能幫助到大家。

什么是Filter

在java的javax.servlet下有一個接口Filter。任何實現了Filter接口的類都可以稱之為filter。Filter的主要用途是設置字符集、控制權限、控制轉向等等。在使用filter的過程中,如果是傳統的web項目,帶有web.xml文件這種。我們需要在xml里面進行配置。比如下面這樣。

    <filter>
        <description>字符集過濾器</description>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <description>字符集編碼</description>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

這種使用方式直接將我們的請求和響應的字符集全部改為utf-8的形式。

如果是在spingboot這種項目中使用,我們定義好自己的filter類之后,需要使用filterregisterbean將filter進行注入。

Filter隨着項目的啟動而啟動,只初始化一次,隨着web項目的停止而銷毀。

Filter主要用於對用戶請求的預處理和程序返回response的后處理。可以在請求到達servlet之前進行request的處理或者添加頭和一些其他數據。或者在reponse到達之前,修改response的頭和數據。

filter中總共有三個方法。
void init(FilterConfig config):用於完成Filter的初始化。
void destory():用於filter銷毀前,完成資源的回收。
void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):該方法是filter的核心過濾方法。通過request進行請求處理,然后調用chain.doFilter。調用完之后,可以通過response進行響應處理。

攔截器

攔截器是aop的一種實現方案,是aop思想的體現。在我們調用方法之前,調用攔截器的一個方法或者在調用方法之后,調用攔截器的一個方法。

SpringMVC 中的Interceptor 攔截請求是通過HandlerInterceptor 來實現的。在SpringMVC 中定義一個Interceptor 非常簡單,主要有兩種方式,第一種方式是要定義的Interceptor類要實現了Spring 的HandlerInterceptor 接口,或者是這個類繼承實現了HandlerInterceptor 接口的類,比如Spring 已經提供的實現了HandlerInterceptor 接口的抽象類HandlerInterceptorAdapter ;第二種方式是實現Spring的WebRequestInterceptor接口,或者是繼承實現了WebRequestInterceptor的類。

(1)preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,該方法將在請求處理之前進行調用。SpringMVC 中的Interceptor 是鏈式調用,在一個應用中或者說是在一個請求中可以同時存在多個Interceptor。每個Interceptor 的調用會依據它的聲明順序依次執行,而且最先執行的都是Interceptor 中的preHandle 方法,所以可以在這個方法中進行一些前置初始化操作或者是對當前請求的一個預處理,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。該方法的返回值是布爾值Boolean類型的,當它返回為false時,表示請求結束,后續的Interceptor和Controller都不會再執行;當返回值為true時就會繼續調用下一個Interceptor的preHandle方法,如果已經是最后一個Interceptor的時候就會是調用當前請求的Controller方法。

(2)postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解釋我們知道這個方法包括后面要說到的afterCompletion方法都只能是在當前所屬的Interceptor的preHandle方法的返回值為true時才能被調用。postHandle方法,顧名思義就是在當前請求進行處理之后,也就是Controller方法調用之后執行,但是它會在DispatcherServlet進行視圖返回渲染之前被調用,所以我們可以在這個方法中對Controller處理之后的ModelAndView對象進行操作。postHandle方法被調用的方向跟preHandle是相反的,也就是說先聲明的Interceptor的postHandle方法反而會后執行。

(3)afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,該方法也是需要當前對應的Interceptor 的preHandle 方法的返回值為true 時才會執行。顧名思義,該方法將在整個請求結束之后,也就是在DispatcherServlet 渲染了對應的視圖之后執行。這個方法的主要作用是用於進行資源清理工作的。
執行的順序如下:

需要注意的點就是當preHandler為true的時候,postHandler才能執行。當為false的時候,afterCompletion仍然會執行。

filter和interceptor的區別總結

1、filter接口在javax.servlet包下面。inteceptor定義在org.springframework.web.servlet中。
2、filter是servlet規定的,interceptor即可用於web程序,也可用於application中。
3、filter是servlet容器支持的,interceptor是spring框架支持的。
4、filter通過dochain放行,interceptor通過prehandler放行。
5、filter只在方法前后執行,interceptor粒度更細,可以深入到方法前后,異常拋出前后。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM