上篇博客我們聊了《JavaEE開發之SpringMVC中的路由配置及參數傳遞詳解》,本篇博客我們就聊一下自定義攔截器的實現、以及使用ModelAndView對象將Controller的值加載到JSTL上、最后再聊一下異常的捕獲處理。這些在日常開發中都是經常使用的東西。具體請看下方內容。
一、自定義攔截器
顧名思義,攔截器是負責攔截某些東西的工具。本部分我們創建的攔截器是負責攔截請求的。這個攔截器類似於高速收費站,只要是想上高速的,都得經過我這個攔截器才可以。也就是說,接下來我們所創建的攔截器就類似於收費站的作用、所有的用戶請求都會經過我們這個攔截器。廢話少說,接下來我們就來創建一個攔截器,並部署到我們的Spring中。
1、自定義攔截器的創建
接下來我們就要創建自定義攔截器了,首先我們創建一個Java類,命名為CustomInterceptor。因為我們要創建的是Spring中的攔截器,所以要繼承與springframework中的HandlerInterceptorAdapter抽象類。創建CustomInterceptor類的過程如下

HandlerInterceptorAdapter是Spring框架中自定義攔截器的適配器,我們可以看一下HandlerInterceptorAdapter抽象類的具體實現,下方是我們關聯的Spring框架的源代碼中的HandlerInterceptorAdapter抽象類的實現。
從下方源代碼中我們不難看出HandlerInterceptorAdapter抽象類實現了AsyncHandlerInterceptor接口,在HandlerInterceptorAdapter的每個方法中並沒有具體實現什么東西,所以我們繼承HandlerInterceptorAdapter后,要對相應的方法進行實現。這些方法會在攔截用戶請求的特定階段去執行,下方會具體介紹到。

2、自定義攔截器中相應方法的重寫
下方代碼段就是我們CustomInterceptor類中所重寫的方法。preHandle()方法會在請求處理之前執行,postHandle()方法會在請求處理后執行,afterCompletion()方法會在請求完成並攔截完成后執行。下方是對相應的方法進行了重寫。
1 public class CustomInterceptor extends HandlerInterceptorAdapter { 2 //請求處理之前執行的方法 3 @Override 4 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 5 throws Exception { 6 System.out.println("在請求處理之前執行該方法-preHandle"); 7 request.setAttribute("startTime", System.currentTimeMillis()); 8 return true; 9 } 10 11 //在請求處理之后執行該方法 12 @Override 13 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 14 ModelAndView modelAndView) throws Exception { 15 System.out.println("在請求處理之后執行該方法-postHandle"); 16 long startTime = (Long) request.getAttribute("startTime"); 17 long handleTime = System.currentTimeMillis() -startTime; 18 System.out.println("本次請求花費了:" + handleTime + "ms\n"); 19 } 20 21 //請求處理完成所執行的方法 22 @Override 23 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 24 throws Exception { 25 System.out.println("請求處理完成所執行的方法-afterCompletion"); 26 } 27 28 }
3.配置自定義攔截器
創建完相應的攔截器后,我們還需將其配置到Spring中該攔截器才起作用。因為我們的Spring配置類繼承了WebMvcConfigurerAdapter抽象類,而在WebMvcConfigurerAdapter抽象類中就有添加攔截器的方法addInterceptors()。我們可以重寫此方法,通過該方法我們可以添加多個攔截器。
下方截圖中的代碼段就是在Spring的配置文件中來配置Interceptor的代碼段。首先我們創建了一個自定義攔截器Bean,然后將攔截器的Bean通過addInterceptors()方法添加到Spring中即可。如下所示:

4、攔截器的測試
創建以及配置好攔截器后,我們就開始測試了。Tomcat重啟后,我們發起網絡請求。下方是控制台打出的log信息。從輸出結果我們不難看出,只要有網絡請求,就會執行攔截器中相應的方法。如下所示:

二、將Controller返回的信息展示到JSP模板(ModelAndView)
本部分是為下一部分做鋪墊的,本部分所做的事情就是將Controller中路由所映射的方法所返回的內容輸出到JSTL模板上。當然主要還是用到了spring框架中的ModelAndView對象。該對象會將返回的信息與JSTL模板上的參數進行綁定,然后在JPS頁面上進行顯示,當然這與PHP中的Smarty模板引擎的工作方式是極為相似的。下方就使用ModelAndView對象將信息輸出到JSTL模板上。
1.創建JSTL模板文件
首先我們創建接納Controller返回信息的頁面模板,在此我們在src/main/resources目錄的views下面創建一個message.jsp文件。文本內容比較簡單,只有一個JSTL標簽${message_key}, 該標簽可以接受Controller中相應的方法所返回的信息。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>${message_key}</h1> </body> </html>
2、給JSTL標簽賦值
接下來所做的就是在相應的Controller相應的方法中給message_key標簽綁定相應的值,並在相應的模板文件中進行顯示。接下來我們就來創建一個ModelViewController控制器類,來負責值的綁定。下方代碼段就是我們的ModeViewController的實現內容。
主要還是ModelAndView的使用。首先我們創建了一個ModelAndView的對象,在ModelAndView的構造器中傳入的參數就是JSTL模板所在的JSP頁面的文件名。然后ModelAndView對象通過調用addObject()方法對“message_key”進行了“Hello world”的值的綁定,最后將modelAndView對象進行返回。如下所示:

3、對頁面的訪問
實現完Controller以及相應的JSP文件后,接下來我們就該對其進行訪問了。下方是對相應路由的訪問結果,從輸出結果中我們可以看出,${message_key}的值就是相應Controller中所返回的值。

三、異常的統一處理
接下來我們就來捕獲拋出的異常,並將異常信息通過ModelAndView的對象交付給指定錯誤處理頁面來顯示。要實現該功能,主要用到的注解是@ControllerAdvice和@ExceptionHandel注解。首先我們將創建的Java類ExceptionHandlerAdvice使用注解@ControllerAdvice進行修飾,然后將exception()方法使用@ExceptionHandler進行注解,使其成為處理異常的方法。
在exception()方法中使用ModelAndView對象將錯誤信息交付給error.jsp進行顯示即可。

定義完處理異常的Advice后,接下來就該拋出個異常來測試一下我們異常處理的方法了。下方的這個AdviceController就是我們測試類,其中拋出了一個異常。具體代碼如下所示:

下方是我們訪問“/advice”路由所返回的結果,可以看出,拋出的異常以及在exception()方法中進行處理了。

今天的博客就先到這兒吧、下篇博客會繼續更新關於SpringMVC的東西。
github代碼分享地址:https://github.com/lizelu/SpringMVCWithMaven
