1.css
Spring MVC 的處理器攔截器相似於 Servlet 開發中的過濾器 Filter,用於對處理器進行預處理和後處理。 用戶能夠本身定義一些攔截器來實現特定的功能。 談到攔截器,還要向你們提一個詞——攔截器鏈(Interceptor Chain)。攔截器鏈就是將攔截器按必定的順 序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其以前定義的順序被調用。 說到這裏,可能你們腦海中有了一個疑問,這不是咱們以前學的過濾器嗎?是的它和過濾器是有幾分類似,但 是也有區別,接下來咱們就來講說他們的區別: 過濾器是 servlet 規範中的一部分, 任何 java web 工程均可以使用。 攔截器是 SpringMVC 框架本身的,只有使用了 SpringMVC 框架的工程才能用。 過濾器在 url-pattern 中配置了/*以後,能夠對全部要訪問的資源攔截。 攔截器它是隻會攔截訪問的控制器方法,若是訪問的是 jsp, html,css,image 或者 js 是不會進行攔 截的。 它也是 AOP 思想的具體應用。 咱們要想自定義攔截器, 要求必須實現: HandlerInterceptor 接口。
2.做用過程html
攔截器的做用對象的controller,攔截器有個放行的功能,能夠在放行以前和以後編寫一些代碼java
預處理,在請求controller以前,會先通過攔截器web
後處理,在請求controller以後,跳轉某個頁面以前,會通過攔截器spring
攔截器鏈,也就是會有多個攔截器,好比第一個攔截器放行了,會再通過第二個攔截器...一直到沒有了,纔會執行controller,返回依然。spring-mvc
1.index.jspmvc
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>攔截器</title> </head> <body> <h3>攔截器</h3> <a href="user/testInterceptor">測試攔截器</a> </body> </html>
2.跳轉成功頁面success.jsp,會有一個在控制檯輸出的代碼,方便演示app
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>跳轉成功</h3> <%System.out.println("run success.jsp...");%> </body> </html>
3.跳轉失敗的頁面error.jsp框架
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>跳轉失敗頁面</h3> </body> </html>
@Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testInterceptor") public String testInterceptor(){ System.out.println("run testInterceptor()..."); return "success"; } }
攔截器須要實現HandlerInterceptor類,這個類有三個方法jsp
1.preHandle()方法
這裏先演示第一個方法,也就是在controller執行以前的方法
public class MyInterceptor implements HandlerInterceptor { /** * 預處理,controller執行以前執行這個方法 * @param request * @param response * @param handler * @return true,表示放行,會執行這個方法的代碼,而後再執行下一個攔截器,若是沒有,則執行controller中的方法; * false則表示不放行,也就是隻執行這個方法的代碼,不會執行controller中的方法,能夠經過request和response直接跳轉到某個頁面 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("run MyInterceptor1.preHandle()..."); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); return true; } }
攔截器須要在springmvc.xml配置文件中配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.cong.controller"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--配置攔截器--> <mvc:interceptors> <mvc:interceptor> <!--要攔截的具體的方法--> <mvc:mapping path="/user/*"/> <!--不要攔截的具體的方法--> <!--<mvc:exclude-mapping path=""/>--> <!--配置攔截器對象--> <bean class="com.cong.interceptor.MyInterceptor"/> </mvc:interceptor> <!--配置第二個攔截器要另外寫一個mvc:interceptor--> <!--<mvc:interceptor></mvc:interceptor>--> </mvc:interceptors> <mvc:annotation-driven></mvc:annotation-driven> </beans>
結果,根據打印的內容,能夠看出,
先是執行了攔截器的preHandle()方法,而後放行,執行controller中的方法,最後跳轉到success.jsp頁面
若是, 將preHandle()方法的返回值設置爲false,那麼就是攔截器不容許經過,
也就是不會執行controller中的方法,再取消註釋,手動跳轉到error.jsp頁面
結果以下,根據控制檯的打印內容,
先是執行了攔截器的preHandle()方法,而後不放行,再也不執行controller中的方法,直接跳轉到error.jsp頁面
2.postHandle()方法
在preHandle()的基礎上添加一個postHandle()方法
public class MyInterceptor implements HandlerInterceptor { /** * 預處理,controller執行以前執行這個方法 * @param request * @param response * @param handler * @return true,表示放行,執行下一個攔截器,若是沒有,則執行controller中的方法; * false則表示不放行,能夠經過request和response直接跳轉到某個頁面 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("run MyInterceptor1.preHandle()..."); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); return true; } /** * 後處理的方法,當controller的方法執行完,要進行頁面跳轉了(也就是執行success.jsp),就會先這個方法 * 也能夠直接進行頁面跳轉 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("run MyInterceptor1.postHandle()..."); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); } }
結果以下,也就是先執行了preHandle()方法,而後執行controller中的方法,再執行postHandle()方法,最後跳轉到success.jsp頁面
postHandle()沒有返回值,可是同樣能夠直接進行頁面跳轉,若是直接進行頁面跳轉,結果以下
也就是先執行了preHandle()方法,而後執行controller中的方法,再執行postHandle()方法,最後跳轉到error.jsp頁面
(雖然打印了run success.jsp... 但實際上並無跳轉到success。jsp)
3.afterCompletion()方法
public class MyInterceptor implements HandlerInterceptor { /** * 預處理,controller執行以前執行這個方法 * @param request * @param response * @param handler * @return true,表示放行,執行下一個攔截器,若是沒有,則執行controller中的方法; * false則表示不放行,能夠經過request和response直接跳轉到某個頁面 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("run MyInterceptor1.preHandle()..."); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); return true; } /** * 後處理的方法,當controller的方法執行完,要進行頁面跳轉了(也就是執行success.jsp),就會先這個方法 * 也能夠直接進行頁面跳轉 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("run MyInterceptor1.postHandle()..."); //request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); } /** * success.jsp執行以後再執行的方法,通常用做釋放資源 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("run MyInterceptor1.afterCompletion()..."); } }
結果以下,也就是afterComplition()方法是在頁面跳轉以後再進行執行的
在這裏,再寫一個攔截器
public class MyInterceptor2 implements HandlerInterceptor { /** * 預處理,controller執行以前執行這個方法 * @param request * @param response * @param handler * @return true,表示放行,執行下一個攔截器,若是沒有,則執行controller中的方法; * false則表示不放行,能夠經過request和response直接跳轉到某個頁面 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("run MyInterceptor2.preHandle()..."); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); return true; } /** * 後處理的方法,當controller的方法執行完,要進行頁面跳轉了(也就是執行success.jsp),就會通過這個方法 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("run MyInterceptor2.postHandle()..."); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response); } /** * success.jsp執行以後再執行的方法,通常用做釋放資源 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("run MyInterceptor2.afterCompletion()..."); } }
注入到容器中
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/user/*"/> <bean class="com.cong.interceptor.MyInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.cong.interceptor.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
執行的過程以下