定義攔截器,實現HandlerInterceptor
接口。接口中提供三個方法。java
public class HandlerInterceptor1 implements HandlerInterceptor{ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //return false表示攔截,不向下執行 //return true表示放行 return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
能夠從名稱和參數看出各個接口的順序和做用:web
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
springmvc攔截器針對HandlerMapping進行攔截設置,若是在某個HandlerMapping中配置攔截,通過該HandlerMapping映射成功的handler最終使用該攔截器。spring
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="handlerInterceptor1"/> <ref bean="handlerInterceptor2"/> </list> </property> </bean> <bean id="handlerInterceptor1" class="com.tianlang.intercapter.HandlerInterceptor1"/> <bean id="handlerInterceptor2" class="com.tianlang.intercapter.HandlerInterceptor2"/>
通常不推薦使用。session
springmvc配置相似全局的攔截器,springmvc框架將配置的相似全局的攔截器注入到每一個HandlerMapping中。mvc
<!--攔截器 --> <mvc:interceptors> <!--多個攔截器,順序執行 --> <mvc:interceptor> <!-- /**表示全部url包括子url路徑 --> <mvc:mapping path="/**"/> <bean class="com.tianlang.interceptor.HandlerInterceptor1"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.tianlang.interceptor.HandlerInterceptor2"></bean> </mvc:interceptor> </mvc:interceptors>
測試多個攔截器各個方法執行時機app
訪問/items/queryItems.action
框架
DEBUG [http-apr-8080-exec-1] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-1] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-1] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-1] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-1] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle HandlerInterceptor2...preHandle DEBUG [http-apr-8080-exec-1] - Fetching JDBC Connection from DataSource DEBUG [http-apr-8080-exec-1] - Registering transaction synchronization for JDBC Connection DEBUG [http-apr-8080-exec-1] - Returning JDBC Connection to DataSource HandlerInterceptor2...postHandle HandlerInterceptor1...postHandle DEBUG [http-apr-8080-exec-1] - Rendering view [org.springframework.web.servlet.view.JstlView: name 'items/itemsList'; URL [/WEB-INF/jsp/items/itemsList.jsp]] in DispatcherServlet with name 'springmvc' DEBUG [http-apr-8080-exec-1] - Added model object 'itemtypes' of type [java.util.HashMap] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Added model object 'itemsQueryVo' of type [com.iot.learnssm.firstssm.po.ItemsQueryVo] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Added model object 'org.springframework.validation.BindingResult.itemsQueryVo' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Added model object 'itemsList' of type [java.util.ArrayList] to request in view with name 'items/itemsList' DEBUG [http-apr-8080-exec-1] - Forwarding to resource [/WEB-INF/jsp/items/itemsList.jsp] in InternalResourceView 'items/itemsList' HandlerInterceptor2...afterCompletion HandlerInterceptor1...afterCompletion DEBUG [http-apr-8080-exec-1] - Successfully completed request
總結:preHandle方法按順序執行,postHandle和afterCompletion按攔截器配置的逆向順序執行。jsp
2.攔截器1放行,攔截器2不放行post
DEBUG [http-apr-8080-exec-8] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-8] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-8] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-8] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-8] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle HandlerInterceptor2...preHandle HandlerInterceptor1...afterCompletion DEBUG [http-apr-8080-exec-8] - Successfully completed request
總結:測試
3.兩個攔截器都不放
DEBUG [http-apr-8080-exec-9] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-9] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-9] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-9] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-9] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle DEBUG [http-apr-8080-exec-9] - Successfully completed request
總結:
4.攔截器1不放行,攔截器2放行
DEBUG [http-apr-8080-exec-8] - DispatcherServlet with name 'springmvc' processing GET request for [/ssm1/items/queryItems.action] DEBUG [http-apr-8080-exec-8] - Looking up handler method for path /items/queryItems.action DEBUG [http-apr-8080-exec-8] - Returning handler method [public org.springframework.web.servlet.ModelAndView com.iot.learnssm.firstssm.controller.ItemsController.queryItems(javax.servlet.http.HttpServletRequest,com.iot.learnssm.firstssm.po.ItemsQueryVo) throws java.lang.Exception] DEBUG [http-apr-8080-exec-8] - Returning cached instance of singleton bean 'itemsController' DEBUG [http-apr-8080-exec-8] - Last-Modified value for [/ssm1/items/queryItems.action] is: -1 HandlerInterceptor1...preHandle DEBUG [http-apr-8080-exec-8] - Successfully completed request
和兩個攔截器都不行的結果一致,由於攔截器1先執行,沒放行
根據測試結果,對攔截器應用。
好比:統一日誌處理攔截器,須要該攔截器preHandle必定要放行,且將它放在攔截器連接中第一個位置。
好比:登錄認證攔截器,放在攔截器連接中第一個位置。權限校驗攔截器,放在登錄認證攔截器以後。(由於登錄經過後才校驗權限,固然登陸認證攔截器要放在統一日誌處理攔截器後面)
@Controller public class LoginController { // 登錄 @RequestMapping("/login") public String login(HttpSession session, String username, String password) throws Exception { // 在session中保存用戶身份信息 session.setAttribute("username", username); // 重定向到商品列表頁面 return "redirect:/items/queryItems.action"; } // 退出 @RequestMapping("/logout") public String logout(HttpSession session) throws Exception { // 清除session session.invalidate(); // 重定向到商品列表頁面 return "redirect:/items/queryItems.action"; } }
/** * 登錄認證攔截器 */ public class LoginInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //獲取請求的url String url = request.getRequestURI(); //判斷url是不是公開地址(實際使用時將公開 地址配置配置文件中) if(url.indexOf("login.action")>=0){ //若是進行登錄提交,放行 return true; } //判斷session HttpSession session = request.getSession(); //從session中取出用戶身份信息 String username = (String) session.getAttribute("username"); if(username != null){ //身份存在,放行 return true; } //執行這裏表示用戶身份須要認證,跳轉登錄頁面 request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("LoginInterceptor...postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("LoginInterceptor...afterCompletion"); } }
<!--攔截器 --> <mvc:interceptors> <!--多個攔截器,順序執行 --> <!-- 登錄認證攔截器 --> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.tianlang.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>