欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Mvc中攔截器Interceptor用法解讀

 更新時(shí)間:2025年03月25日 10:03:39   作者:透明果凍  
這篇文章主要介紹了Spring Mvc中攔截器Interceptor用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、概述

攔截器常用于在請(qǐng)求處理的不同階段插入自定義邏輯。

Spring MVC的攔截器作用是在請(qǐng)求到達(dá)控制器之前或之后進(jìn)行攔截,可以對(duì)請(qǐng)求和響應(yīng)進(jìn)行一些特定的處理。

如:

  • 登錄驗(yàn)證:對(duì)于需要登錄才能訪問的網(wǎng)址,使用攔截器可以判斷用戶是否已登錄,如果未登錄則跳轉(zhuǎn)到登錄頁面。
  • 權(quán)限校驗(yàn):根據(jù)用戶權(quán)限對(duì)部分網(wǎng)址進(jìn)行訪問控制,拒絕未經(jīng)授權(quán)的用戶訪問。
  • 請(qǐng)求日志:記錄請(qǐng)求信息,例如請(qǐng)求地址、請(qǐng)求參數(shù)、請(qǐng)求時(shí)間等,用于排查問題和性能優(yōu)化。
  • 更改響應(yīng):可以對(duì)響應(yīng)的內(nèi)容進(jìn)行修改,例如添加頭信息、調(diào)整響應(yīng)內(nèi)容格式等。

二、攔截器和過濾器之間的區(qū)別

關(guān)于過濾器可以看我之前的文章過濾器Filter的介紹和使用。

我們很容易發(fā)現(xiàn)攔截器和過濾器十分相似,他們都是對(duì)某一階段的前后進(jìn)行攔截,進(jìn)行一些處理。那么他們之間有什么不同呢?

過濾器(Filter)是servlet中定義的,而攔截器(HandlerInterceptor)則是由Spring MVC框架提供

二者所作用的范圍不同

  • 過濾器更注重在**請(qǐng)求和響應(yīng)(即在Servlet之前)**的流程中進(jìn)行處理,可以修改請(qǐng)求和響應(yīng)的內(nèi)容,例如設(shè)置編碼和字符集、請(qǐng)求頭、狀態(tài)碼等。
  • 攔截器則更加側(cè)重于對(duì)控制器進(jìn)行前置或后置處理,在請(qǐng)求到達(dá)控制器之前或之后進(jìn)行特定的操作,例如打印日志、權(quán)限驗(yàn)證等。

三、自定義實(shí)現(xiàn)攔截器

Spring MVC 提供了 HandlerInterceptor 接口,開發(fā)者可以通過實(shí)現(xiàn)這個(gè)接口來創(chuàng)建自定義的攔截器。

其中定義了三個(gè)默認(rèn)方法,用于對(duì)不同階段進(jìn)行攔截:

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):
  • 在控制器方法執(zhí)行前調(diào)用。
  • 返回 true 表示繼續(xù)執(zhí)行后續(xù)的攔截器和控制器方法;返回 false 表示中斷執(zhí)行,不再調(diào)用后續(xù)的攔截器和控制器方法。
  • 可以用于權(quán)限驗(yàn)證、日志記錄等。
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):
  • 在控制器方法執(zhí)行后,但在視圖渲染前調(diào)用。
  • 可以用于修改 ModelAndView 對(duì)象,添加額外的數(shù)據(jù)等。
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):
  • 在整個(gè)請(qǐng)求處理完成后調(diào)用,無論是否發(fā)生異常。
  • 可以用于資源清理、日志記錄等。

創(chuàng)建自定義攔截器:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在控制器方法執(zhí)行前調(diào)用
        System.out.println("preHandle..." );
        //這里我們直接返回true
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在控制器方法執(zhí)行后,但在視圖渲染前調(diào)用
        System.out.println("postHandle...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整個(gè)請(qǐng)求處理完成后調(diào)用
        System.out.println("AfterCompletion");
    }
}

此時(shí)要想要該攔截器生效,我們還需在spring mvc配置文件中進(jìn)行配置(默認(rèn)對(duì)所有控制器進(jìn)行攔截)

<mvc:interceptors>
    <mvc:interceptor>
        <!--設(shè)置要攔截的路徑-->
        <mvc:mapping path="/**"/>
        <!--指定不進(jìn)行攔截的路徑-->
        <mvc:exclude-mapping path="/test"/>
        <!--配置自定義攔截器的類路徑-->
        <bean class="com.example.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

也可以通過在自定義 攔截器的類上加上@component注解,此時(shí)的配置文件為

<mvc:interceptors>
    <mvc:interceptor>
        <!--設(shè)置要攔截的路徑-->
        <mvc:mapping path="/**"/>
        <!--指定不進(jìn)行攔截的路徑-->
        <mvc:exclude-mapping path="/test"/>
        <!--默認(rèn)名字為類名首字母小寫-->
        <ref bean="myInterceptor"></ref>
    </mvc:interceptor>
</mvc:interceptors>

四、多個(gè)攔截器的執(zhí)行順序

在 Spring MVC 中,多個(gè)攔截器可以組成一個(gè)攔截器鏈,按照注冊(cè)(配置)順序依次執(zhí)行。

假設(shè)現(xiàn)在按順序注冊(cè)三個(gè)攔截器Interceptor1,Interceptor2,Interceptor3。

當(dāng)所有的攔截器的preHandle方法都返回true時(shí):

  • preHandle執(zhí)行順序:Interceptor1->Interceptor2->Interceptor3 (順序執(zhí)行)
  • postHandle執(zhí)行順序:Interceptor3->Interceptor2->Interceptor1 (逆序執(zhí)行)
  • afterCompletion執(zhí)行順序:Interceptor3->Interceptor2->Interceptor1 (逆序執(zhí)行)

當(dāng)某一個(gè)攔截器的preHandle方法返回false時(shí),這里假設(shè)為Interceptor3

  • preHandle執(zhí)行順序:Interceptor1->Interceptor2->Interceptor3 (順序執(zhí)行直到某一個(gè)攔截器返回false)
  • postHandle不執(zhí)行,控制器方法也不執(zhí)行
  • afterCompletion執(zhí)行順序:Interceptor2->Interceptor1 (返回false的攔截器之前的攔截器逆序執(zhí)行)

為什么是這樣的順序呢?我們觀察源碼可以發(fā)現(xiàn):

  • preHandle源碼分析
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
   		 //interceptorList是一個(gè)ArrayList集合,按順序存放了所有的攔截器	
    	//下標(biāo)從0開始,從這里我們可以知道為什么是順序執(zhí)行的。
  		//this.interceptorIndex = i++,注意這個(gè)代碼,如果返回false,則它的值則表示當(dāng)前返回false的攔截器的下標(biāo)
        for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
            HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
            //如果返回false
            if (!interceptor.preHandle(request, response, this.handler)) {
                //執(zhí)行AfterCompletion,這里我們就知道為什么不執(zhí)行postHandle,而執(zhí)行AfterCompletion了
                this.triggerAfterCompletion(request, response, (Exception)null);
                return false;
            }
        }

        return true;
    }
  • postHandle源碼分析
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
    	//可以看到這里是從最后一個(gè)攔截器開始逆序遍歷
        for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
            HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
            interceptor.postHandle(request, response, this.handler, mv);
        }

    }
  • afterCompletion源碼分析
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
    	//this.interceptorList.size() - 1表示當(dāng)前返回false的攔截器的上一個(gè)的下標(biāo)
    	//注意這里是--i
    	//這也就解釋了為什么是返回false的攔截器之前的攔截器逆序執(zhí)行
        for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
            HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
            interceptor.postHandle(request, response, this.handler, mv);
        }

    }

總結(jié)

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

相關(guān)文章

  • 解決分頁插件pagehelper在SpringBoot不起作用的問題

    解決分頁插件pagehelper在SpringBoot不起作用的問題

    這篇文章主要介紹了解決分頁插件pagehelper在SpringBoot不起作用的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring RestTemplate基本使用介紹

    Spring RestTemplate基本使用介紹

    這篇文章主要介紹了Spring RestTemplate基本使用介紹,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 一文搞懂hashCode()和equals()方法的原理

    一文搞懂hashCode()和equals()方法的原理

    這篇文章主要介紹了詳解hashCode()和equals()的本質(zhì)區(qū)別和聯(lián)系,本文先對(duì)兩種方法作了介紹,然后對(duì)二者聯(lián)系進(jìn)行分析,具有一定參考價(jià)值,需要的朋友可以了解下
    2020-06-06
  • java兩種單例模式用法分析

    java兩種單例模式用法分析

    這篇文章主要介紹了java兩種單例模式用法,結(jié)合實(shí)例形式對(duì)比分析了java實(shí)現(xiàn)單例模式的兩種常見技巧,需要的朋友可以參考下
    2016-08-08
  • Eclipse 出現(xiàn)Failed to load JavaHL Library解決方法

    Eclipse 出現(xiàn)Failed to load JavaHL Library解決方法

    這篇文章主要介紹了Eclipse 出現(xiàn)Failed to load JavaHL Library解決方法的相關(guān)資料,今天使用Eclipse 時(shí)出現(xiàn)以上錯(cuò)誤,本文說明如何更更正,需要的朋友可以參考下
    2016-11-11
  • Java 反射機(jī)制原理與用法詳解

    Java 反射機(jī)制原理與用法詳解

    這篇文章主要介紹了Java 反射機(jī)制原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了Java反射機(jī)制的相關(guān)概念、原理、基本使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-11-11
  • java用list集合存儲(chǔ)學(xué)生信息并算出成績平均值操作

    java用list集合存儲(chǔ)學(xué)生信息并算出成績平均值操作

    這篇文章主要介紹了java用list集合存儲(chǔ)學(xué)生信息并算出成績平均值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • MyBatis中的模糊查詢語句

    MyBatis中的模糊查詢語句

    這篇文章主要介紹了MyBatis中的模糊查詢語句的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • maven導(dǎo)入本地倉庫jar包,報(bào):Could?not?find?artifact的解決

    maven導(dǎo)入本地倉庫jar包,報(bào):Could?not?find?artifact的解決

    這篇文章主要介紹了maven導(dǎo)入本地倉庫jar包,報(bào):Could?not?find?artifact的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java多線程生產(chǎn)者消費(fèi)者模式實(shí)現(xiàn)過程解析

    Java多線程生產(chǎn)者消費(fèi)者模式實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Java多線程生產(chǎn)者消費(fèi)者模式實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評(píng)論