SpringMVC攔截器創建配置及執行順序
SpringMVC攔截器介紹
springMVC 中的攔截器用於攔截控制器方法的執行。
先創建出前置需要的一些條件:
<a th:href="@{/testInterceptor}" rel="external nofollow" >測試攔截器</a>
後端:
@Controller public class TestController { @RequestMapping("/testInterceptor") public String testInterceptor() { return "success"; } }
一、創建攔截器
新建一個包 interceptors,在下面創建一個攔截器 FirstInterceptor ,並且要實現 HandlerInterceptor 接口。
快捷鍵Ctrl + O,快速重寫方法,圖示裡的 3 個。
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
: 在當前控制器方法執行之前執行。
postHandle
: 在當前控制器方法執行之後執行。
afterCompletion
:處理完視圖和模型數據,渲染視圖完畢之後執行。
二、配置攔截器
在 springMVC 配置文件裡配置攔截器,對象就是FirstInterceptor 類:
<!-- 配置攔截器 --> <mvc:interceptors> <bean class="com.pingguo.mvc.interceptors.FirstInterceptor"></bean> </mvc:interceptors>
重新部署,訪問http://localhost:8080/springmvc/,發現頁面空白,查看控制器日志看到有打印:
說明攔截成功。
看下上面重新的三個方法中,隻有preHandle有返回值,是個佈爾類型:false 表示攔截,true 表示放行。
修改上面preHandle的返回為 true,重新部署後再次訪問首頁,可以訪問成功。
查看控制臺打印輸出,看到在渲染之前,前面2個方法執行瞭:preHandle、postHandle 。
在非常多的 Thymeleaf 渲染之後,最後一個 afterCompletion 也執行瞭。
現在繼續點擊首頁裡的新加的超鏈接,發現也會被攔截放行。
說明這種配置方式,會攔截所有的請求。
設置不需要攔截的請求
可以通過 ref 或 bean 標簽設置攔截器:
- 通過mvc:mapping設置需要攔截的請求通過
- mvc:exclude-mapping設置需要排除的請求
<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>
註意這裡我在外部註冊瞭一個 bean 叫 firstInterceptor,以便 ref 引用。
- <mvc:mapping path="/**"/>,表示攔截所有請求。
- <mvc:exclude-mapping path="/">,表示除瞭首頁不攔截。
也就是說,現在我訪問http://localhost:8080/springmvc/的時候,應該不攔截。
訪問http://localhost:8080/springmvc/testInterceptor就會攔截瞭。
試一下,先訪問 http://localhost:8080/springmvc/:
可以正常打開首頁,並且控制臺也沒有輸出攔截器裡的內容:
現在繼續訪問 http://localhost:8080/springmvc/testInterceptor,
攔截瞭。
三、多個攔截器的執行順序
繼續新建一個攔截器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>
重新部署,訪問下首頁http://localhost:8080/springmvc/,查看控制臺打印輸出。
可以發現,preHandle 方法執行的順序是 FirstInterceptor->SecondInterceptor。其他 2 個方法則是順序倒過來。
若每個攔截器的 preHandle()都返回 true:
- 執行順序跟配置裡的順序有關,在上面攔截器裡 firstInterceptor 就是在 secondInterceptor前面。
- preHandle()會按照配置的順序執行,而postHandle()和afterComplation()`會按照配置的反序執行。
若某個攔截器的preHandle()返回瞭false:
- preHandle()返回false和它之前的攔截器的preHandle()都會執行。
- postHandle()都不執行。
- 返回false的攔截器之前的攔截器的afterComplation()會執行。
試一下,把 SecondInterceptor 中的preHandle()修改返回 false,再次請求下首頁:
符合預期。
這些過程可以打斷點看下源碼的執行過程。
以上就是SpringMVC攔截器創建配置及執行順序的詳細內容,更多關於SpringMVC攔截器配置的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- SpringMVC實現文件上傳與下載、攔截器、異常處理器等功能
- 詳解SpringMVC的攔截器鏈實現及攔截器鏈配置
- 詳解SpringMVC HandlerInterceptor攔截器的使用與參數
- SpringMVC攔截器超詳細解讀
- 詳解Spring MVC的攔截器與異常處理機制