SpringBoot攔截器的配置使用介紹
1. 配置攔截器
具體步驟:
編寫一自定義攔截器類實(shí)現(xiàn)接口 HandlerInterceptor
HandlerInterceptor 接口: 可在三處進(jìn)行攔截——目標(biāo)方法執(zhí)行之前、目標(biāo)方法執(zhí)行完成、頁面渲染以后攔截
public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
將攔截器注冊(cè)到容器中,實(shí)現(xiàn) WebMvcConfigurer 中的 addInteraptor,然后將自定義攔截器注冊(cè)到攔截器中
指定攔截器規(guī)則 —— 攔截所有 '/**'
,靜態(tài)資源也會(huì)被攔截
解決靜態(tài)資源同時(shí)被攔截問題:
- 在
addPathPatterns
中精確指定精確需要攔截資源 - 在
excludePathPatterns
中指定排除靜態(tài)資源
可在 application.properties 文件中指定靜態(tài)資源統(tǒng)一前綴,方便排除靜態(tài)資源
spring.mvc.static-path-pattern=/static/**
2. 一個(gè)小 Demo
實(shí)現(xiàn)未登錄用戶不能訪問除登錄頁外其他頁面的小Demo
1. 自定義攔截器類—LoginInterceptor
自定義登錄攔截器,實(shí)現(xiàn)檢測(cè)到用戶未登錄,則攔截用戶對(duì)其他資源的訪問,并返回到登錄頁面
package com.wanqing.admin.interceptor; import lombok.extern.slf4j.Slf4j; import org.apache.catalina.Session; import org.springframework.lang.Nullable; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /* 登錄檢查 */ @Slf4j // lombok 提供的功能 public class LoginInterceptor implements HandlerInterceptor { // 目標(biāo)方法執(zhí)行之前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("攔截的路徑是{}", request.getRequestURI()); // 登錄檢查邏輯 HttpSession session = request.getSession(); Object loginUser = session.getAttribute("loginUser"); if(loginUser != null){ return true; // 放行 } // 攔截住,重定向到登錄頁面 request.setAttribute("msg", "未登錄不允許訪問"); request.getRequestDispatcher("/").forward(request, response); // 轉(zhuǎn)發(fā)到當(dāng)前請(qǐng)求 return false; } // 目標(biāo)方法執(zhí)行之后 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } // 頁面渲染完成之后 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
2. 將攔截器注冊(cè)到容器中
通過下列方法,將攔截器注冊(cè)到容器中,并配置好要攔截的路徑和要放行的路徑。本次 demo 中若未登錄則所有路徑都攔截,只放行登錄頁面
package com.wanqing.admin.config; import com.wanqing.admin.interceptor.LoginInterceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class AdminWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 在攔截器的注冊(cè)中心里,添加 Login 攔截器 registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") //所有請(qǐng)求都被攔截,靜態(tài)資源也被攔截 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); // 放行的請(qǐng)求 } }
3. 原理分析
1. 根據(jù)當(dāng)前請(qǐng)求,找到HandlerExecutionChainand,即得到可以處理請(qǐng)求的 Handler,以及 Handler 的所有攔截器
處理器執(zhí)行鏈 :
2. 先順序執(zhí)行所有攔截器的preHandle
方法
- 如果返回為true執(zhí)行下一個(gè)攔截器的
preHandle
; - 若為 false,直接倒敘執(zhí)行所有已經(jīng)執(zhí)行了的攔截器的
afterCompletion
方法
Step into:
if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }
攔截器方法執(zhí)行 源碼分析:
HandlerExecutionChain.class
—— 順序執(zhí)行所有攔截器的preHandle
方法
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) { HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i); if (!interceptor.preHandle(request, response, this.handler)) { this.triggerAfterCompletion(request, response, (Exception)null); return false; } }
—— 倒敘執(zhí)行所有已經(jīng)執(zhí)行了的攔截器的 afterCompletion
方法
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) { for(int i = this.interceptorIndex; i >= 0; --i) { HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i); try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable var7) { logger.error("HandlerInterceptor.afterCompletion threw exception", var7); } } }
3. 如果任何一個(gè)攔截器返回 false,直接跳出不執(zhí)行目標(biāo)方法
4. 所有攔截器都返回 true,執(zhí)行目標(biāo)方法
5. 目標(biāo)方法執(zhí)行后,倒敘執(zhí)行所有攔截器的 postHandle 方法
6. 前面的步驟有任何異常都會(huì)直接觸發(fā) afterCompletion 方法
7. 頁面成果渲染完成之后,也會(huì)倒敘觸發(fā) afterCompletion 方法
圖解:
到此這篇關(guān)于SpringBoot攔截器的配置使用介紹的文章就介紹到這了,更多相關(guān)SpringBoot攔截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea gradle項(xiàng)目復(fù)制依賴小技巧(推薦)
這篇文章主要介紹了idea gradle項(xiàng)目復(fù)制依賴小技巧,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11java中@JSONField和@JsonProperty注解的使用說明及對(duì)比
@JSONField與@JsonProperty隸屬兩個(gè)不同的包,前者是阿里系的fastjson包,后者是spring?boot官方使用的jackson包,本文主要介紹了java中@JSONField和@JsonProperty注解的使用說明及對(duì)比,感興趣的可以了解一下2023-11-11解決kafka:org.apache.kafka.common.errors.TimeoutException問題
這篇文章主要介紹了解決kafka:org.apache.kafka.common.errors.TimeoutException問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Hadoop?MapReduce實(shí)現(xiàn)單詞計(jì)數(shù)(Word?Count)
這篇文章主要為大家詳細(xì)介紹了如何利用Hadoop實(shí)現(xiàn)單詞計(jì)數(shù)(Word?Count)的MapReduce,文中的示例代碼講解詳細(xì),感興趣的可以跟隨小編一起學(xué)習(xí)一下2023-05-05SpringBoot集成screw實(shí)現(xiàn)數(shù)據(jù)庫文檔生成的代碼示例
數(shù)據(jù)庫設(shè)計(jì)文檔是項(xiàng)目技術(shù)文檔的重要組成部分,Screw 是一款開源的數(shù)據(jù)庫文檔生成工具,它支持多種數(shù)據(jù)庫類型,并能生成豐富格式的文檔,本文將通過一個(gè)實(shí)際的例子,展示如何使用 Spring Boot 集成 Screw 生成數(shù)據(jù)庫設(shè)計(jì)文檔2024-07-07Idea中maven項(xiàng)目實(shí)現(xiàn)登錄驗(yàn)證碼功能
這篇文章主要介紹了Idea中maven項(xiàng)目實(shí)現(xiàn)登錄驗(yàn)證碼功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Spring?框架的?MethodInterceptor?簡(jiǎn)介及示例代碼
MethodInterceptor接口定義了一個(gè)方法Object?intercept(Object?obj,?Method?method,?Object[]?args,?MethodProxy?proxy)?,該方法在代理對(duì)象的方法被調(diào)用時(shí)被觸發(fā),這篇文章主要介紹了Spring?框架的?MethodInterceptor?簡(jiǎn)介及示例代碼,需要的朋友可以參考下2023-09-09Hibernate映射解析之關(guān)聯(lián)映射詳解
所謂關(guān)聯(lián)映射就是將關(guān)聯(lián)關(guān)系映射到數(shù)據(jù)庫里,在對(duì)象模型中就是一個(gè)或多個(gè)引用。下面這篇文章詳細(xì)的給大家介紹了Hibernate映射解析之關(guān)聯(lián)映射的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-02-02Java常見啟動(dòng)命令-jar、-server和-cp詳細(xì)比較
這篇文章主要給大家介紹了關(guān)于Java常見啟動(dòng)命令-jar、-server和-cp詳細(xì)比較的相關(guān)資料,該文總結(jié)了常歸的jar包的啟動(dòng)方式,并分析各種啟動(dòng)方式的區(qū)別,需要的朋友可以參考下2023-07-07