SpringMVC攔截器創(chuàng)建配置及執(zhí)行順序
SpringMVC攔截器介紹
springMVC 中的攔截器用于攔截控制器方法的執(zhí)行。
先創(chuàng)建出前置需要的一些條件:
<a th:href="@{/testInterceptor}" rel="external nofollow" >測(cè)試攔截器</a>
后端:
@Controller public class TestController { @RequestMapping("/testInterceptor") public String testInterceptor() { return "success"; } }
一、創(chuàng)建攔截器
新建一個(gè)包 interceptors,在下面創(chuàng)建一個(gè)攔截器 FirstInterceptor ,并且要實(shí)現(xiàn) HandlerInterceptor 接口。
快捷鍵Ctrl + O,快速重寫(xiě)方法,圖示里的 3 個(gè)。
public class FirstInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("FirstInterceptor --> preHandle"); return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("FirstInterceptor --> postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("FirstInterceptor --> afterCompletion"); } }
preHandle
: 在當(dāng)前控制器方法執(zhí)行之前執(zhí)行。
postHandle
: 在當(dāng)前控制器方法執(zhí)行之后執(zhí)行。
afterCompletion
:處理完視圖和模型數(shù)據(jù),渲染視圖完畢之后執(zhí)行。
二、配置攔截器
在 springMVC 配置文件里配置攔截器,對(duì)象就是FirstInterceptor 類:
<!-- 配置攔截器 --> <mvc:interceptors> <bean class="com.pingguo.mvc.interceptors.FirstInterceptor"></bean> </mvc:interceptors>
重新部署,訪問(wèn)http://localhost:8080/springmvc/,發(fā)現(xiàn)頁(yè)面空白,查看控制器日志看到有打印:
說(shuō)明攔截成功。
看下上面重新的三個(gè)方法中,只有preHandle有返回值,是個(gè)布爾類型:false 表示攔截,true 表示放行。
修改上面preHandle的返回為 true,重新部署后再次訪問(wèn)首頁(yè),可以訪問(wèn)成功。
查看控制臺(tái)打印輸出,看到在渲染之前,前面2個(gè)方法執(zhí)行了:preHandle、postHandle 。
在非常多的 Thymeleaf 渲染之后,最后一個(gè) afterCompletion 也執(zhí)行了。
現(xiàn)在繼續(xù)點(diǎn)擊首頁(yè)里的新加的超鏈接,發(fā)現(xiàn)也會(huì)被攔截放行。
說(shuō)明這種配置方式,會(huì)攔截所有的請(qǐng)求。
設(shè)置不需要攔截的請(qǐng)求
可以通過(guò) ref 或 bean 標(biāo)簽設(shè)置攔截器:
- 通過(guò)mvc:mapping設(shè)置需要攔截的請(qǐng)求通過(guò)
- mvc:exclude-mapping設(shè)置需要排除的請(qǐng)求
<bean name="firstInterceptor" class="com.pingguo.mvc.interceptors.FirstInterceptor"></bean> <!-- 配置攔截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/"></mvc:exclude-mapping> <ref bean="firstInterceptor"></ref> </mvc:interceptor> </mvc:interceptors>
注意這里我在外部注冊(cè)了一個(gè) bean 叫 firstInterceptor,以便 ref 引用。
- <mvc:mapping path="/**"/>,表示攔截所有請(qǐng)求。
- <mvc:exclude-mapping path="/">,表示除了首頁(yè)不攔截。
也就是說(shuō),現(xiàn)在我訪問(wèn)http://localhost:8080/springmvc/的時(shí)候,應(yīng)該不攔截。
訪問(wèn)http://localhost:8080/springmvc/testInterceptor就會(huì)攔截了。
試一下,先訪問(wèn) http://localhost:8080/springmvc/:
可以正常打開(kāi)首頁(yè),并且控制臺(tái)也沒(méi)有輸出攔截器里的內(nèi)容:
現(xiàn)在繼續(xù)訪問(wèn) http://localhost:8080/springmvc/testInterceptor,
攔截了。
三、多個(gè)攔截器的執(zhí)行順序
繼續(xù)新建一個(gè)攔截器SecondInterceptor,注意這次我加了 @Component,方便在配置文件中直接ref引用使用。
@Component public class SecondInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("SecondInterceptor --> preHandle"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("SecondInterceptor --> postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("SecondInterceptor --> afterCompletion"); } }
修改攔截器配置:
<!-- 配置攔截器 --> <mvc:interceptors> <ref bean="firstInterceptor"></ref> <ref bean="secondInterceptor"></ref> </mvc:interceptors>
重新部署,訪問(wèn)下首頁(yè)http://localhost:8080/springmvc/,查看控制臺(tái)打印輸出。
可以發(fā)現(xiàn),preHandle 方法執(zhí)行的順序是 FirstInterceptor->SecondInterceptor。其他 2 個(gè)方法則是順序倒過(guò)來(lái)。
若每個(gè)攔截器的 preHandle()都返回 true:
- 執(zhí)行順序跟配置里的順序有關(guān),在上面攔截器里 firstInterceptor 就是在 secondInterceptor前面。
- preHandle()會(huì)按照配置的順序執(zhí)行,而postHandle()和afterComplation()`會(huì)按照配置的反序執(zhí)行。
若某個(gè)攔截器的preHandle()返回了false:
- preHandle()返回false和它之前的攔截器的preHandle()都會(huì)執(zhí)行。
- postHandle()都不執(zhí)行。
- 返回false的攔截器之前的攔截器的afterComplation()會(huì)執(zhí)行。
試一下,把 SecondInterceptor 中的preHandle()修改返回 false,再次請(qǐng)求下首頁(yè):
符合預(yù)期。
這些過(guò)程可以打斷點(diǎn)看下源碼的執(zhí)行過(guò)程。
以上就是SpringMVC攔截器創(chuàng)建配置及執(zhí)行順序的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC攔截器配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MyBatis獲取插入記錄的自增長(zhǎng)字段值(ID)
本文分步驟給大家介紹了MyBatis獲取插入記錄的自增長(zhǎng)字段值的方法,在文中給大家提到了mybatis返回插入數(shù)據(jù)的自增長(zhǎng)id,需要的朋友可以參考下2017-11-11解讀Mapper與Mapper.xml文件之間匹配的問(wèn)題
這篇文章主要介紹了解讀Mapper與Mapper.xml文件之間匹配的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法
Java語(yǔ)言的Calendar(日歷),Date(日期),和DateFormat(日期格式)組成了Java標(biāo)準(zhǔn)的一個(gè)基本但是非常重要的部分,下面這篇文章主要給大家介紹了關(guān)于java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法的相關(guān)資料,需要的朋友可以參考下2023-12-12Java終止循環(huán)體的具體實(shí)現(xiàn)
這篇文章主要介紹了Java終止循環(huán)體的具體實(shí)現(xiàn),需要的朋友可以參考下2014-02-02如何在Spring?Boot中使用OAuth2認(rèn)證和授權(quán)
這篇文章主要介紹了如何在Spring?Boot中使用OAuth2認(rèn)證和授權(quán)的相關(guān)資料,OAuth2.0是一種開(kāi)放的授權(quán)協(xié)議,它允許用戶授權(quán)第三方應(yīng)用訪問(wèn)其賬戶(或資源),而無(wú)需共享其用戶賬戶憑據(jù),需要的朋友可以參考下2023-12-12flyway實(shí)現(xiàn)java 自動(dòng)升級(jí)SQL腳本的問(wèn)題及解決方法
大家在平時(shí)開(kāi)發(fā)自己寫(xiě)SQL語(yǔ)句忘記在所有環(huán)境執(zhí)行,需要新增環(huán)境做數(shù)據(jù)遷移,那么遇到這樣的問(wèn)題該如何解決呢?本文通過(guò)場(chǎng)景分析給大家介紹java 自動(dòng)升級(jí)SQL腳本的策略,感興趣的朋友一起看看吧2021-07-07