SpringMVC攔截器配置
阿新 • • 發佈:2018-03-24
SpringMVC 攔截器 攔截器顧名思義就是用於攔截訪問請求的,我們可以在攔截器裏對訪問請求進行事先的處理,例如權限檢查、記錄日誌、驗證請求數據等等。說白了就是我們可以在請求到控制器之前對其進行一個處理。
攔截器基本上和過濾器是類似的,只不過攔截器提供的方法比較實用,參數也比較多,而且攔截器是受到spring容器的管理的。
實現攔截器很簡單,只需要實現spring裏的HandlerInterceptor接口並實現接口中的三個方法即可,如下示例:
package org.zero01.test; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("TestInterceptor--攔截器的preHandle方法被執行了"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { System.out.println("TestInterceptor--攔截器的postHandle方法被執行了"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("TestInterceptor--攔截器的afterCompletion方法被執行了"); } }
註:在springmvc4.x版本中這三個方法都是必須要實現的,而在springmvc5.x版本中則不是必須實現的。
關於這三個方法的執行順序:
- preHandle方法在請求到控制器之前被執行,也就是預處理方法,該方法的返回值決定請求是否發送到控制器中,true是發送,類似於filter中的doFilter,false則是中斷
- postHandle方法在控制器之後被執行,此時我們可以通過modelAndView參數對象對模型數據或對視圖數據進行處理
- afterCompletion方法在整個請求處理完畢時執行,即在視圖渲染完畢時回調,如性能監控中我們可以在此記錄結束時間並輸出消耗時間,還可以進行一些資源的清理
完成攔截器的編寫後,在Spring配置文件中,裝配這個攔截器:
<mvc:interceptors>
<bean class="org.zero01.test.TestInterceptor"/>
</mvc:interceptors>
然後編寫控制器代碼如下:
package org.zero01.test; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { @RequestMapping("/test/test.do") public String test(){ System.out.println("控制器--test方法被執行了"); return "index"; } }
通過瀏覽器訪問後,控制臺打印結果如下:
TestInterceptor--攔截器的preHandle方法被執行了
控制器--test方法被執行了
TestInterceptor--攔截器的postHandle方法被執行了
TestInterceptor--攔截器的afterCompletion方法被執行了
註:攔截器是在DispatcherServlet之後的,如果DispatcherServlet報錯的話,攔截器是不會被執行的。
以上是正常的流程,我們來看看中斷的流程,把preHandle方法中的返回值改成false,如下:
...
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("TestInterceptor--攔截器的preHandle方法被執行了");
return false;
}
...
通過瀏覽器訪問後,控制臺打印結果如下:
TestInterceptor--攔截器的preHandle方法被執行了
從控制臺的打印結果中可以看到,請求沒有被發送到控制器上,而是在攔截器這裏中斷了。
springmvc裏有個<mvc:mapping/>
標簽,通過這個標簽我們可以配置攔截器只攔截哪些路徑下的請求:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/test/**"/>
<bean class="org.zero01.test.TestInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
如上配置,表示指定攔截器只攔截/test/
下的所有請求。如果是其他請求則不會觸發攔截器。
除此之外,我們還可以通過<mvc:exclude-mapping/>
標簽來指定哪個uri的請求不會被攔截器攔截,例如我們指定了攔截器攔截/test/
目錄下的所有請求,但是我希望訪問/test/test.do
的請求不被攔截器攔截,則可以使用這個標簽進行配置,如下:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/test/**"/>
<mvc:exclude-mapping path="/test/test.do"/>
<bean class="org.zero01.test.TestInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
如上配置,表示訪問/test/test.do
的請求不會觸發攔截器。
SpringMVC攔截器配置