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

Springboot項(xiàng)目快速實(shí)現(xiàn)攔截器功能

 更新時(shí)間:2023年03月28日 09:22:02   作者:凡夫販夫  
上一篇文章介紹了Springboot項(xiàng)目如何快速實(shí)現(xiàn)過(guò)濾器功能,本篇文章接著來(lái)盤(pán)一盤(pán)攔截器,仔細(xì)研究后會(huì)發(fā)現(xiàn),其實(shí)攔截器和過(guò)濾器的功能非常類似,可以理解為面向切面編程的一種具體實(shí)現(xiàn)。感興趣的小伙伴可以參考閱讀

前言

上一篇文章分享了Springboot項(xiàng)目快速實(shí)現(xiàn)過(guò)濾器功能,本篇文章接著來(lái)盤(pán)一盤(pán)攔截器,仔細(xì)研究后會(huì)發(fā)現(xiàn),其實(shí)攔截器和過(guò)濾器的功能非常類似,可以理解為面向切面編程的一種具體實(shí)現(xiàn)。下面就其功能特性、工作原理、涉及到的核心類以及具體的實(shí)現(xiàn)方式幾個(gè)方面進(jìn)行梳理,以便在實(shí)際業(yè)務(wù)開(kāi)發(fā)過(guò)程中,可以根據(jù)實(shí)際需要選擇合適的實(shí)現(xiàn)訪求。

環(huán)境配置

jdk版本:1.8

開(kāi)發(fā)工具:Intellij iDEA 2020.1

springboot:2.3.9.RELEASE

HandleInterceptor介紹

攔截器,在java中只是一種概念,并沒(méi)有一個(gè)具體的實(shí)現(xiàn)或標(biāo)準(zhǔn),通常所說(shuō)的java web的攔截器實(shí)際是指HandleInterceptor接口,這是Spring MVC提供的一套攔截機(jī)制,可以在controller處理請(qǐng)求之后和響應(yīng)處理結(jié)果之后,對(duì)請(qǐng)求信息和響應(yīng)結(jié)果進(jìn)行攔截;但不能修改具體的請(qǐng)求信息和響應(yīng)結(jié)果;Spring MVC的攔截器的概念和servlet的Filter非常類似,但是在執(zhí)行順序上是有所不同的,下面會(huì)重點(diǎn)介紹;從本質(zhì)上來(lái)說(shuō),SpringMVC的攔截器機(jī)制,是AOP(面向切面編程)的一種具體實(shí)現(xiàn),可以很方面用戶對(duì)實(shí)際業(yè)務(wù)中公共的一些業(yè)務(wù)進(jìn)行橫向抽取,但是和servlet的Filter一樣,有一定的局限性,如能對(duì)請(qǐng)求信息和響應(yīng)結(jié)果進(jìn)行攔截,但不能修改具體的請(qǐng)求信息和響應(yīng)結(jié)果;能攔截controller層的方法,但是不能攔截service層的方法;

工作原理

如果把過(guò)濾器和攔截器放在一起來(lái)分析其工作原理,就需要再次明確一件事:Filter接口的全限定類名是javax.servlet.Filter,HandleInterceptor接口的全限定類名是org.springframework.web.servlet.HandlerInterceptor,從這里就可以看得出來(lái),F(xiàn)ilter是servlet里就有的接口,HandleInterceptor是Spring中新增的接口,兩個(gè)是來(lái)源完全不同的東西,但功能卻很類似,那么放在一起又會(huì)發(fā)生什么奇妙的事呢?

1、過(guò)濾器1、過(guò)濾器2、攔截1、攔截2對(duì)象,會(huì)在Spring容器啟動(dòng)的過(guò)程中,完成bean的注冊(cè);

2、當(dāng)客戶端向服務(wù)端發(fā)起http請(qǐng)求時(shí),在請(qǐng)求到達(dá)具體的controller方法之前,會(huì)先經(jīng)過(guò)過(guò)濾器、攔截器的處理,其中過(guò)濾器的執(zhí)行時(shí)機(jī)要早于攔截器;和過(guò)濾器一樣,如果當(dāng)前請(qǐng)求匹配到了多個(gè)攔截器,會(huì)形成一個(gè)攔截器鏈,按照默認(rèn)或指定的優(yōu)先級(jí),依次經(jīng)過(guò)各個(gè)攔截器對(duì)象的處理之后,才會(huì)到達(dá)具體的controller方法;

3、到達(dá)具體的controller方法后,開(kāi)始業(yè)務(wù)處理;得到業(yè)務(wù)處理結(jié)果后,響應(yīng)結(jié)果也會(huì)經(jīng)過(guò)請(qǐng)求進(jìn)來(lái)時(shí)的所有過(guò)濾器、攔截器的處理,不同的是順序與請(qǐng)求進(jìn)來(lái)時(shí)完全相反,即先進(jìn)后出;

實(shí)現(xiàn)方式

1、實(shí)現(xiàn)org.springframework.web.servlet.HandlerInterceptor接口;

2、繼承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter類;

核心類

HandlerInterceptor

HandlerInterceptor是SpringMVC提供的實(shí)現(xiàn)攔截器功能的一個(gè)標(biāo)準(zhǔn)接口,接口內(nèi)有三個(gè)方法:

1、preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) ,方法在請(qǐng)求處理之前會(huì)被調(diào)用。該方法在 Interceptor 類中最先執(zhí)行,用來(lái)進(jìn)行一些前置初始化操作或是對(duì)當(dāng)前請(qǐng)求做預(yù)處理,也可以進(jìn)行一些判斷來(lái)決定請(qǐng)求是否要繼續(xù)進(jìn)行下去。該方法的返回值是 Boolean 類型;當(dāng)它返回 false 時(shí),表示請(qǐng)求結(jié)束,后續(xù)的 Interceptor 和 Controller 都不會(huì)再執(zhí)行;當(dāng)它返回為 true 時(shí),會(huì)繼續(xù)調(diào)用下一個(gè) Interceptor 的 preHandle 方法,如果已經(jīng)是最后一個(gè) Interceptor 的時(shí)候就會(huì)調(diào)用當(dāng)前請(qǐng)求的 Controller 方法;

2、postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 方法在當(dāng)前請(qǐng)求處理完成之后,也就是 Controller 方法調(diào)用之后執(zhí)行,但是它會(huì)在 DispatcherServlet 進(jìn)行視圖返回渲染之前被調(diào)用,所以我們可以在這個(gè)方法中對(duì) Controller 處理之后的 ModelAndView 對(duì)象進(jìn)行操作;

3、afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法需要在當(dāng)前對(duì)應(yīng)的 Interceptor 類的 preHandle 方法返回值為 true 時(shí)才會(huì)執(zhí)行;該方法將在整個(gè)請(qǐng)求結(jié)束之后,也就是在 DispatcherServlet 渲染了對(duì)應(yīng)的視圖之后執(zhí)行,主要用來(lái)進(jìn)行資源清理或釋放。

HandlerInterceptorAdapter

HandlerInterceptorAdapter是一個(gè)抽象類,該抽象類實(shí)現(xiàn)了AsyncHandlerInterceptor接口,而AsyncHandlerInterceptor接口又繼承于HandlerInterceptor,因此可以認(rèn)為HandlerInterceptorAdapter是實(shí)現(xiàn)了HandlerInterceptor接口,但是HandlerInterceptorAdapter是抽象類,實(shí)際上并沒(méi)有具體實(shí)現(xiàn),所以在實(shí)現(xiàn)攔截器功能功能的兩種方式本質(zhì)上是一種;

代碼實(shí)現(xiàn)

定義兩個(gè)攔截器:MyInterceptor1和MyInterceptor2,通過(guò)一次完成的請(qǐng)求,來(lái)分析一下HandlerInterceptor接口的preHandle()、postHandle()、afterCompletion()是如何工作的?

1、定義和注冊(cè)兩個(gè)攔截器:MyInterceptor1和MyInterceptor2,設(shè)置攔截器的攔截路徑為/person/get*,myInterceptor2的優(yōu)先級(jí)高于myInterceptor1;

2、發(fā)起http請(qǐng)求(URL:/person/get);

3、/person/get請(qǐng)求在執(zhí)行PersonController#getPerson()之前,會(huì)先執(zhí)行到MyInterceptor1和MyInterceptor2的preHandler()方法;

4、如果MyInterceptor1和MyInterceptor2的preHandler()方法返回都為true,則會(huì)執(zhí)行到PersonController#getPerson();

5、PersonController#getPerson()執(zhí)行完成后,還沒(méi)有返回視圖渲染對(duì)象之前MyInterceptor1和MyInterceptor2的postHandle()方法觸發(fā)執(zhí)行;

6、再然后就是整個(gè)請(qǐng)求處理完之后,MyInterceptor1和MyInterceptor2的afterCompletion()方法觸發(fā)執(zhí)行;

PersonController.java

@Controller
@RequestMapping("/person")
@Slf4j
public class PersonController {
    @Autowired
    private IPersonService personService;
    @GetMapping("/get")
    @ResponseBody
    public Person getPerson(Integer id) {
        Person person = this.personService.get(id);
        log.info("http://查詢person詳情執(zhí)行完成");
        return person;
    }
}

定義WebConfig類實(shí)現(xiàn)WebMvcConfigurer接口,實(shí)現(xiàn)addInterceptors(),完成攔截器的注冊(cè)以及設(shè)置好攔截路徑和優(yōu)先級(jí)順序;

@Configuration
public class WebConfig  implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(new MyInterceptor2())
        .addPathPatterns("/person/get*")
        .order(1);
         registry.addInterceptor(new MyInterceptor1())
        .addPathPatterns("/person/get*")//設(shè)置攔截請(qǐng)求路徑;*是通配符;
        .order(2)//設(shè)置攔截器對(duì)象的優(yōu)先級(jí),如果有多個(gè)攔截器對(duì)象,設(shè)置數(shù)字越小,優(yōu)先級(jí)越高;
        .excludePathPatterns("/test");//設(shè)置排除攔截的請(qǐng)求路徑;
    }
}

定義MyInterceptor1類實(shí)現(xiàn)HandlerInterceptor接口

@Slf4j
public class MyInterceptor1 implements HandlerInterceptor {
    //preHandle方法在請(qǐng)求處理之前被調(diào)用;當(dāng)返回true,則表示可以繼續(xù)后續(xù)請(qǐng)求處理;當(dāng)返回false,則表示請(qǐng)求結(jié)束;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("http://myInterceptor1的preHandle方法開(kāi)始執(zhí)行");
        log.info("http://請(qǐng)求路徑:{}",request.getRequestURI());
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        log.info("http://攔截類:{},方法:{}",handlerMethod.getBean().getClass().getName(),handlerMethod.getMethod().getName());
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String parameterName = parameterNames.nextElement();
            String parameterValue = request.getParameter(parameterName);
            log.info("http://請(qǐng)求參數(shù)>{}:{}",parameterName,parameterValue);
        }
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("http://myInterceptor1的postHandle方法開(kāi)始執(zhí)行");
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("http://myInterceptor1的afterCompletion方法開(kāi)始執(zhí)行");
    }
}

定義MyInterceptor2,繼承HandlerInterceptorAdapter抽象類,重寫(xiě)HandlerInterceptorAdapter類的方法;

@Slf4j
public class MyInterceptor2 extends HandlerInterceptorAdapter {
    //preHandle方法在請(qǐng)求處理之前被調(diào)用;當(dāng)返回true,則表示可以繼續(xù)后續(xù)請(qǐng)求處理;當(dāng)返回false,則表示請(qǐng)求結(jié)束;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("http://myInterceptor1的preHandle方法開(kāi)始執(zhí)行");
        log.info("http://請(qǐng)求路徑:{}",request.getRequestURI());
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        log.info("http://攔截類:{},方法:{}",handlerMethod.getBean().getClass().getName(),handlerMethod.getMethod().getName());
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String parameterName = parameterNames.nextElement();
            String parameterValue = request.getParameter(parameterName);
            log.info("http://請(qǐng)求參數(shù)>{}:{}",parameterName,parameterValue);
        }
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("http://myInterceptor1的postHandle方法開(kāi)始執(zhí)行");
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("http://myInterceptor1的afterCompletion方法開(kāi)始執(zhí)行");
    }

結(jié)果驗(yàn)證

Filter與HandleInterceptor的執(zhí)行順序:在請(qǐng)求處理階段,先經(jīng)過(guò)Filter然后再經(jīng)過(guò)HandleInterceptor,在響應(yīng)處理階段,先經(jīng)過(guò)HandleInterceptor,再經(jīng)過(guò)Filter,即先進(jìn)后出;

總結(jié)

攔截器的功能與Filter比較類似,實(shí)現(xiàn)方式也比較簡(jiǎn)單,需要特別注意的是攔截器的執(zhí)行時(shí)機(jī)稍晚于過(guò)濾器。那么Spring的AOP與過(guò)濾器、攔截器相比,又有哪些不同和需要注意的事項(xiàng)呢?下一篇文章會(huì)把這個(gè)坑給填上。

到此這篇關(guān)于Springboot項(xiàng)目快速實(shí)現(xiàn)攔截器功能的文章就介紹到這了,更多相關(guān)Springboot實(shí)現(xiàn)攔截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Java的Socket編寫(xiě)的C/S聊天程序?qū)崿F(xiàn)

    基于Java的Socket編寫(xiě)的C/S聊天程序?qū)崿F(xiàn)

    這篇文章主要介紹了基于Java的Socket編寫(xiě)的C/S聊天程序?qū)崿F(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java實(shí)現(xiàn)AES加密和解密方式完整示例

    Java實(shí)現(xiàn)AES加密和解密方式完整示例

    這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)AES加密和解密方式的相關(guān)資料,AES加密為最常見(jiàn)的對(duì)稱加密算法,是一種區(qū)塊加密標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用,需要的朋友可以參考下
    2023-10-10
  • Java中的CGLIB動(dòng)態(tài)代理的使用及原理詳解

    Java中的CGLIB動(dòng)態(tài)代理的使用及原理詳解

    這篇文章主要介紹了Java中的CGLIB動(dòng)態(tài)代理的使用及原理詳解,CGLIB是一個(gè)功能強(qiáng)大,高性能的代碼生成包,它為沒(méi)有實(shí)現(xiàn)接口的類提供代理,為JDK的動(dòng)態(tài)代理提供了很好的補(bǔ)充,需要的朋友可以參考下
    2023-09-09
  • Idea如何關(guān)閉或開(kāi)啟引用提示Usages和Annotations

    Idea如何關(guān)閉或開(kāi)啟引用提示Usages和Annotations

    這篇文章主要介紹了Idea如何關(guān)閉或開(kāi)啟引用提示Usages和Annotations問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java中類與對(duì)象的使用詳情

    java中類與對(duì)象的使用詳情

    這篇文章主要介紹了java中類與對(duì)象的使用詳情,面向?qū)ο笫峭ㄟ^(guò)類和對(duì)象去描述和代表萬(wàn)千事物對(duì)象的,首先我們需要知道如何去定義一個(gè)類,下面文章我們?cè)敿?xì)介紹兩者的使用方法,需要的小伙伴可以參考一下
    2022-05-05
  • FeignClient如何通過(guò)配置變量調(diào)用配置文件url

    FeignClient如何通過(guò)配置變量調(diào)用配置文件url

    這篇文章主要介紹了FeignClient如何通過(guò)配置變量調(diào)用配置文件url,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • java實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)小游戲(源碼加注釋)

    java實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)小游戲(源碼加注釋)

    這篇文章主要介紹了java實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)小游戲(源碼加注釋),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • 幾句話說(shuō)清session,cookie和token的區(qū)別及說(shuō)明

    幾句話說(shuō)清session,cookie和token的區(qū)別及說(shuō)明

    這篇文章主要介紹了幾句話說(shuō)清session,cookie和token的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • IDEA未配置SQL方言:無(wú)法使用SQL提示解決方法

    IDEA未配置SQL方言:無(wú)法使用SQL提示解決方法

    在使用IDEA進(jìn)行SQL開(kāi)發(fā)時(shí),如果未配置SQL方言可能會(huì)導(dǎo)致一些問(wèn)題,如無(wú)法正確識(shí)別數(shù)據(jù)庫(kù)中的關(guān)鍵字、數(shù)據(jù)類型等,這篇文章主要給大家介紹了關(guān)于IDEA未配置SQL方言,無(wú)法使用SQL提示解決方法的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • Spring Boot 配置文件(application.yml、application-dev.yml、application-test.yml)

    Spring Boot 配置文件(application.yml、application-dev.y

    本文主要介紹了Spring Boot 配置文件,主要包含application.yml、application-dev.yml、application-test.yml,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03

最新評(píng)論

五常市| 乌拉特前旗| 蚌埠市| 固原市| 余江县| 黄冈市| 紫金县| 宜章县| 万安县| 武鸣县| 舒城县| 安图县| 科技| 米脂县| 广元市| 徐州市| 屏东市| 绥德县| 寿宁县| 吴忠市| 无为县| 富源县| 漠河县| 会宁县| 永泰县| 嘉义市| 卢氏县| 皋兰县| 乌兰察布市| 左云县| 民县| 拉孜县| 承德市| 江都市| 焦作市| 佛坪县| 墨江| 尤溪县| 郴州市| 邛崃市| 姚安县|