最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解讀過濾器(Filter)與攔截器(Interceptor)的區(qū)別及說明

 更新時間:2025年10月23日 14:24:37   作者:吳名氏.  
這篇文章主要介紹了過濾器(Filter)與攔截器(Interceptor)的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

1 過濾器(Filter)

Servlet 中的過濾器 Filter 實(shí)現(xiàn)了 javax.servlet.Filter 接口的服務(wù)器端程序,主要用途是設(shè)置字符集(CharacterEncodingFilter)、控制權(quán)限、控制轉(zhuǎn)向、用戶是否已經(jīng)登陸、有沒有權(quán)限訪問該頁面等。

其工作原理是,只要你在 web.xml 文件配置好要攔截的客戶端請求,它都會幫你攔截到請求。此時,其實(shí)你可以對請求或響應(yīng)(request、response)統(tǒng)一設(shè)置編碼;它隨 web 應(yīng)用啟動而啟動,只初始化一次,以后就可以攔截相關(guān)請求。只有當(dāng)你的 web 應(yīng)用停止或重新部署的時候才銷毀。

  • Filter 可以認(rèn)為是 Servlet 的一種”加強(qiáng)版”。它主要用于對用戶請求進(jìn)行預(yù)處理,也可以對HttpServletResponse 進(jìn)行后處理,是個典型的處理鏈;
  • Filter 可以對用戶請求生成響應(yīng),和 Servlet 相同;
  • 處理流程:用戶請求 -> Filter 預(yù)處理 -> Servlet 處理請求生成響應(yīng) -> Filter 對響應(yīng)進(jìn)行后處理。

1.1 Filter 的用處

  • 在 HttpServletRequest 到達(dá) Servlet 之前,攔截客戶的 HttpServletRequest;
  • 根據(jù)需要檢查 HttpServletRequest,也可以修改 HttpServletRequest 頭和數(shù)據(jù);
  • 在 HttpServletResponse 到達(dá)客戶端之前,攔截 HttpServletResponse;
  • 根據(jù)需要檢查 HttpServletResponse,也可以修改 HttpServletResponse頭和數(shù)據(jù)。

Filter 有如下幾個種類。

1.2 Filter 的種類

  • 用戶授權(quán)的 Filter:Filter 負(fù)責(zé)檢查用戶請求,根據(jù)請求過濾用戶非法請求;
  • 日志 Filter:詳細(xì)記錄某些特殊的用戶請求;
  • 負(fù)責(zé)解碼的 Filter:包括對非標(biāo)準(zhǔn)編碼的請求解碼;
  • 能改變 XML 內(nèi)容的 XSLT Filter 等。

Filter 可以負(fù)責(zé)攔截多個請求或響應(yīng),一個請求或響應(yīng)也可以被多個 Filter 攔截。

1.3 創(chuàng)建 Filter 的步驟

  1. 創(chuàng)建 Filter 處理類,并實(shí)現(xiàn) javax.servlet.Filter 接口;
  2. web.xml 文件中配置 Filter(或者使用 @WebFilter 注解)。

javax.servlet.Filter 接口中定義了三個方法:

  • void init(FilterConfig config) 用于完成 Filter 的初始化;
  • void destory() 用于 Filter 銷毀前,完成某些資源的回收;
  • void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) 實(shí)現(xiàn)過濾功能。

doFilter 方法就是對每個請求及響應(yīng)增加的額外處理。該方法可以實(shí)現(xiàn)對用戶請求進(jìn)行預(yù)處理(ServletRequest request),也可實(shí)現(xiàn)對服務(wù)器響應(yīng)進(jìn)行后處理(ServletResponse response)。

它們的分界線為,是否調(diào)用了 chain.doFilter()。執(zhí)行該方法之前,即對用戶請求進(jìn)行預(yù)處理;執(zhí)行該方法之后,即對服務(wù)器響應(yīng)進(jìn)行后處理。

2 攔截器(Interceptor)

攔截器是在面向切面編程中應(yīng)用的,就是 service 或一個方法前/后調(diào)用一個方法。是基礎(chǔ) Java 的反射機(jī)制。

攔截不是在 web.xml,而是在 AOP(Aspect-Oriented Programming)中用于某個方法或字段被訪問之前,進(jìn)行攔截。然后在之前或之后加入某些操作,甚至在拋出異常的時候做業(yè)務(wù)邏輯的操作。攔擊器是 AOP 的一種實(shí)現(xiàn)策略。

2.1 攔截器的實(shí)現(xiàn)方式

SpringMVC 中的 Interceptor 攔截請求是通過 HandlerInterceptor 來實(shí)現(xiàn)的。在 SpringMVC 中定義 Interceptor 主要有兩種方式:

  • 實(shí)現(xiàn) Spring 的 HandlerInterceptor 接口或者繼承了實(shí)現(xiàn) HandlerInterceptor 接口的類(比如HandlerInterceptorAdapter);
  • 實(shí)現(xiàn) Spring 的 WebRequestInterceptor 接口,或者繼承了實(shí)現(xiàn)WebRequestInterceptor接口的類。

Interceptor 中的方法:

preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法

顧名思義,該方法將在請求處理之前進(jìn)行調(diào)用。

SpringMVC 中的 Interceptor 是鏈?zhǔn)秸{(diào)用。在一個應(yīng)用中或者說是在一個請求中可以同時存在多個 Interceptor,每個 Interceptor 的調(diào)用會依據(jù)它的聲明順序依次執(zhí)行,而且最先執(zhí)行的都是 Interceptor 中的 preHandle 方法。

所以可以在這個方法中進(jìn)行一些前置初始化操作或者是對當(dāng)前請求的一個預(yù)處理,也可以在這個方法中進(jìn)行一些判斷來決定請求是否要繼續(xù)進(jìn)行下去。該方法的返回值是布爾值 Boolean 類型的,當(dāng)它返回為 false 時,表示請求結(jié)束,后續(xù)的 Interceptor 和Controller 都不會再執(zhí)行;當(dāng)返回值為 true 時就會繼續(xù)調(diào)用下一個 Interceptor 的 preHandle 方法。如果已經(jīng)是最后一個 Interceptor 的時候就會是調(diào)用當(dāng)前請求的Controller 方法。

postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法

由 preHandle 方法的解釋我們知道,這個方法包括后面要說到的 afterCompletion 方法都只能是在當(dāng)前所屬的 Interceptor 的 preHandle 方法的返回值為 true 時才能被調(diào)用。

postHandle 方法,顧名思義就是在當(dāng)前請求進(jìn)行處理之后,也就是 Controller 方法調(diào)用之后執(zhí)行,但是它會在 DispatcherServlet 進(jìn)行視圖返回渲染之前被調(diào)用。所以,我們可以在這個方法中對 Controller 處理之后的 ModelAndView 對象進(jìn)行操作。

postHandle 方法被調(diào)用的方向跟 preHandle 是相反的。也就是說,先聲明的 Interceptor 的 postHandle 方法反而會后執(zhí)行。這和 Struts2 里面的 Interceptor 的執(zhí)行過程有點(diǎn)類似。Struts2 里面的 Interceptor 的執(zhí)行過程也是鏈?zhǔn)降?,只是?Struts2 里面需要手動調(diào)用 ActionInvocation 的 invoke 方法來觸發(fā)對下一個 Interceptor 或者是 Action 的調(diào)用,然后每一個 Interceptor 中在 invoke 方法調(diào)用之前的內(nèi)容都是按照聲明順序執(zhí)行的,而 invoke 方法之后的內(nèi)容就是反向的。

afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法

該方法也是需要當(dāng)前對應(yīng)的 Interceptor 的p reHandle 方法的返回值為 true 時才會執(zhí)行。顧名思義,該方法將在整個請求結(jié)束之后,也就是在 DispatcherServlet 渲染了對應(yīng)的視圖之后執(zhí)行。這個方法的主要作用是用于進(jìn)行資源清理工作的。

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class ExecuteTimeInterceptor extends HandlerInterceptorAdapter{
    private static final Logger logger = Logger.getLogger(ExecuteTimeInterceptor.class);
    //before the actual handler will be executed
    public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler)
        throws Exception {
        long startTime = System.currentTimeMillis();
        request.setAttribute("startTime", startTime);
        return true;
    }

    //after the handler is executed
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
        throws Exception {
        long startTime = (Long)request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        //統(tǒng)計耗時
        long executeTime = endTime - startTime;
        //modified the exisitng modelAndView
        modelAndView.addObject("executeTime",executeTime);

        //log it
        if(logger.isDebugEnabled()){
           logger.debug("[" + handler + "] executeTime : " + executeTime + "ms");
        }
    }
}

2.1.1 非 SpringBoot 項目實(shí)現(xiàn)方式

使用 mvc:interceptors 標(biāo)簽來聲明需要加入到 SpringMVC 攔截器鏈中的攔截器。

<mvc:interceptors>  
<!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 -->  
<bean class="com.company.app.web.interceptor.AllInterceptor"/>  
    <mvc:interceptor>  
         <mvc:mapping path="/**"/>  
         <mvc:exclude-mapping path="/parent/**"/>  
         <bean class="com.company.authorization.interceptor.SecurityInterceptor" />  
    </mvc:interceptor>  
    <mvc:interceptor>  
         <mvc:mapping path="/parent/**"/>  
         <bean class="com.company.authorization.interceptor.SecuritySystemInterceptor" />  
    </mvc:interceptor>  
</mvc:interceptors>

可以利用 mvc:interceptors 標(biāo)簽聲明一系列的攔截器,然后它們就可以形成一個攔截器鏈。攔截器的執(zhí)行順序是按聲明的先后順序執(zhí)行的,先聲明的攔截器中的 preHandle 方法會先執(zhí)行,然而它的 postHandle 方法和 afterCompletion 方法卻會后執(zhí)行。

在 mvc:interceptors 標(biāo)簽下聲明 interceptor 主要有兩種方式:

  • 直接定義一個 Interceptor 實(shí)現(xiàn)類的 bean 對象。使用這種方式聲明的 Interceptor攔截器將會對所有的請求進(jìn)行攔截;
  • 使用 mvc:interceptor 標(biāo)簽進(jìn)行聲明。使用這種方式進(jìn)行聲明的 Interceptor 可以通過 mvc:mapping子標(biāo)簽來定義需要進(jìn)行攔截的請求路徑。

經(jīng)過上述兩步之后,定義的攔截器就會發(fā)生作用對特定的請求進(jìn)行攔截了。

2.1.2 Spring Boot 項目

配置攔截器

@Configuration
//@Configurationpublic
public class WebAppConfigurer implements WebMvcConfigurer {

    /**
     * 配置攔截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 多個攔截器組成一個攔截器鏈
        registry.addInterceptor(new ExecuteTimeInterceptor()).addPathPatterns("/**");

        //API限流攔截
        registry.addInterceptor(accessLimitAjaxInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**","/login.html");
        registry.addInterceptor(accessInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**","/login.html");
    }
}

2.2 攔截器(interceptor)使用

  • 請求到達(dá) DispatcherServlet;
  • DispatcherServlet 發(fā)送至 Interceptor,執(zhí)行 preHandler;
  • 請求到達(dá) Controller;
  • 請求結(jié)束后,執(zhí)行 postHandler。

3 過濾器(Filter)與 攔截器(Interceptor)的區(qū)別

Spring 的 Interceptor(攔截器)與 Servlet 的 Filter 有相似之處,比如二者都是 AOP 編程思想的體現(xiàn),都能實(shí)現(xiàn)權(quán)限檢查、日志記錄等。

不同之處總結(jié)如下:

3.1 執(zhí)行順序

用戶請求 -> 過濾前 -> 攔截前 -> Action處理 -> 攔截后 -> 過濾后 -> 響應(yīng)

4 過濾器(Filter)與 攔截器(Interceptor)常見用途

  • Authentication Filters
  • Logging and Auditing Filtersx
  • Image conversion Filters
  • Data compression Filters
  • Encryption Filters
  • Tokenizing Filters
  • Filters that trigger resource access events
  • XSL/T filters
  • Mime-type chain Filter

Request Filters 可以實(shí)現(xiàn):

  • 執(zhí)行安全檢查
  • 格式化請求頭和主體
  • 審查或者記錄日志
  • 根據(jù)請求內(nèi)容授權(quán)或者限制用戶訪問
  • 根據(jù)請求頻率限制用戶訪問

Response Filters 可以實(shí)現(xiàn):

  • 壓縮響應(yīng)內(nèi)容:比如讓下載的內(nèi)容更小
  • 追加或者修改響應(yīng)
  • 創(chuàng)建或者整體修改響應(yīng)
  • 根據(jù)地方不同修改響應(yīng)內(nèi)容

5 總結(jié)

5.1 過濾器

所謂過濾器顧名思義是用來過濾的。在 Java Web中,傳入的 request、response 提前過濾掉一些信息,或者提前設(shè)置一些參數(shù);然后再傳入 Servlet 或者 Struts 的 action 進(jìn)行業(yè)務(wù)邏輯。比如,過濾掉非法 URL(不是 login.do 的地址請求,如果用戶沒有登陸都過濾掉),或者在傳入 Servlet 或者 Struts 的 action 前統(tǒng)一設(shè)置字符集,或者去除掉一些非法字符(聊天室經(jīng)常用到的,一些罵人的話)。

Filter 流程是線性的, URL 傳來之后,檢查之后,可保持原來的流程繼續(xù)向下執(zhí)行,被下一個 filter、servlet 接收等。

5.2 Java 的攔截器

主要是用在插件上,擴(kuò)展件上比如 Hibernate Spring Struts2等 有點(diǎn)類似面向切片的技術(shù),在用之前先要在配置文件即 XML 文件里進(jìn)行對應(yīng)的聲明。

攔截器(Interceptor)是基于 Java 的反射機(jī)制,而過濾器(Filter)是基于函數(shù)回調(diào)。從靈活性上說攔截器功能更強(qiáng)大些,F(xiàn)ilter 能做的事情,攔截器都能做,而且可以在請求前、請求后執(zhí)行,比較靈活。Filter 主要是針對 URL 地址做一個編碼的事情、過濾掉沒用的參數(shù)、安全校驗(yàn)(比如登錄不登錄之類),太細(xì)的話,還是建議用攔截器。

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java版畫板的實(shí)現(xiàn)方法

    Java版畫板的實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了Java版畫板的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 淺析Java中如何實(shí)現(xiàn)線程之間通信

    淺析Java中如何實(shí)現(xiàn)線程之間通信

    本篇文章主要介紹了淺析Java中如何實(shí)現(xiàn)線程之間通信。針對 Java 的線程間通信進(jìn)行了大致的講解,有興趣的可以了解一下
    2017-04-04
  • SpringBoot項目如何將Bean注入到普通類中

    SpringBoot項目如何將Bean注入到普通類中

    這篇文章主要介紹了SpringBoot項目如何將Bean注入到普通類中,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • spring 事務(wù)實(shí)現(xiàn)的示例

    spring 事務(wù)實(shí)現(xiàn)的示例

    本文主要介紹了spring 事務(wù)實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • 使用maven-assembly-plugin如何將system 依賴范圍的jar以class 方式打包進(jìn) jar包中

    使用maven-assembly-plugin如何將system 依賴范圍的jar以class 方式

    這篇文章主要介紹了使用maven-assembly-plugin如何將system 依賴范圍的jar以class 方式打包進(jìn) jar包中,本文給大家分享完美解決思路,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Mybatis-plus3.4.3下使用lambdaQuery報錯解決

    Mybatis-plus3.4.3下使用lambdaQuery報錯解決

    最近在使用lambdaQuery().eq(CommonUser::getOpenId, openId).one()進(jìn)行查詢報錯,本文主要介紹了Mybatis-plus3.4.3下使用lambdaQuery報錯解決,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • 解析Java的可變長參數(shù)列表及其使用時的注意點(diǎn)

    解析Java的可變長參數(shù)列表及其使用時的注意點(diǎn)

    這篇文章主要介紹了解析Java的可變參數(shù)列表及其使用時的注意點(diǎn),注意可變參數(shù)必須位于最后一項,需要的朋友可以參考下
    2016-03-03
  • JDBC示例代碼

    JDBC示例代碼

    本教程提供了如何創(chuàng)建一個簡單的JDBC應(yīng)用程序的示例。演示如何打開一個數(shù)據(jù)庫連接,執(zhí)行SQL查詢,并顯示結(jié)果
    2014-03-03
  • Java中對集合的元素排序操作方法

    Java中對集合的元素排序操作方法

    本文介紹了Java中對集合元素進(jìn)行排序的幾種常見方法,包括使用Collections.sort()、List.sort()、StreamAPI以及對Map的鍵或值進(jìn)行排序,每種方法都有其適用的場景和使用方式,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • JAVAE中servlet的概念及使用示例詳解

    JAVAE中servlet的概念及使用示例詳解

    servlet是一種實(shí)現(xiàn)動態(tài)頁面的技術(shù),他是由tomcat提供給程序員的一組API可以幫助程序員開發(fā)一個web程序,這篇文章主要介紹了JAVAE中servlet的概念及使用,需要的朋友可以參考下
    2024-05-05

最新評論

昌平区| 湘阴县| 紫金县| 岢岚县| 仙桃市| 贡觉县| 宁波市| 永善县| 焦作市| 剑河县| 庆阳市| 西乌珠穆沁旗| 绥化市| 郯城县| 遂宁市| 石嘴山市| 赞皇县| 浙江省| 双辽市| 台州市| 通城县| 宣城市| 临朐县| 昌邑市| 五峰| 沽源县| 博乐市| 鹤岗市| 房山区| 岑溪市| 阜阳市| 平谷区| 韶关市| 七台河市| 格尔木市| 武强县| 桑植县| 台中市| 资源县| 句容市| 陆良县|