springmvc配置拦截器及测试详解
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                springmvc配置拦截器及测试详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                
                            
                            
                            攔截器
1.攔截定義
 
定義攔截器,實現HandlerInterceptor接口。接口中提供三個方法。
[java]?view plaincopy package?cn.edu.hpu.ssm.interceptor;??  ??  import?javax.servlet.http.HttpServletRequest;??  import?javax.servlet.http.HttpServletResponse;??  ??  import?org.springframework.web.servlet.HandlerInterceptor;??  import?org.springframework.web.servlet.ModelAndView;??  ??  //測試攔截器1??  public?class?HandlerInterceptor1?implements?HandlerInterceptor{??  ??  ??  ????//執行Handler方法之前執行??  ????//用于身份認證、身份授權??  ????//比如身份認證,如果認證通過表示當前用戶沒有登陸,需要此方法攔截不再向下執行??  ????@Override??  ????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler)?throws?Exception?{??  ??????????  ??????????  ????????//return?false表示攔截,不向下執行??  ????????//return?true表示放行??????????  ????????return?false;??  ????}??  ??????  ????//進入Handler方法之后,返回modelAndView之前執行??  ????//應用場景從modelAndView出發:將公用的模型數據(比如菜單導航)在這里??  ????//傳到視圖,也可以在這里統一指定視圖??  ????@Override??  ????public?void?postHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?ModelAndView?modelAndView)?throws?Exception?{??  ???????????  ??????????  ????}??  ??????  ????//執行Handler完成執行此方法??  ????//應用場景:統一異常處理,統一日志處理??  ????@Override??  ????public?void?afterCompletion(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?Exception?ex)??  ????????????throws?Exception?{??  ???????????  ??????????  ????}??  }??  
 
2.攔截器配置
2.1針對HandlerMapping配置
springmvc攔截器針對HandlerMapping進行攔截設置,如果在某個HandlerMapping中配置攔截,經過該 HandlerMapping映射成功的handler最終使用該攔截器。
[html]?view plaincopy <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="springmvc.intercapter.HandlerInterceptor1"/>??  ????<bean?id="handlerInterceptor2"?class="springmvc.intercapter.HandlerInterceptor2"/>??  
 
一般不推薦使用。
 
 
2.2類似全局的攔截器
springmvc配置類似全局的攔截器,springmvc框架將配置的類似全局的攔截器注入到每個HandlerMapping中。
[html]?view plaincopy <!--?攔截器?-->??  <mvc:interceptors>??  ????<!--?多個攔截器,順序執行?-->??  ????<mvc:interceptor>??  ????????<!--?/**表示所有url包括子url路徑?-->??  ????????<mvc:mapping?path="/**"/>??  ????????<bean?class="cn.edu.hpu.ssm.interceptor.HandlerInterceptor1"/>??  ????</mvc:interceptor>??  ????<mvc:interceptor>??  ????????<mvc:mapping?path="/**"/>??  ????????<bean?class="cn.edu.hpu.ssm.interceptor.HandlerInterceptor2"/>??  ????</mvc:interceptor>??  </mvc:interceptors>??  
 
3.攔截測試
3.1測試需求
測試多個攔截器各各方法執行時機。
 
3.2編寫兩個攔截
HandlerInterceptor1.java:
[java]?view plaincopy package?cn.edu.hpu.ssm.interceptor;??  ??  import?javax.servlet.http.HttpServletRequest;??  import?javax.servlet.http.HttpServletResponse;??  ??  import?org.springframework.web.servlet.HandlerInterceptor;??  import?org.springframework.web.servlet.ModelAndView;??  ??  //測試攔截器1??  public?class?HandlerInterceptor1?implements?HandlerInterceptor{??  ??  ??  ????//執行Handler方法之前執行??  ????//用于身份認證、身份授權??  ????//比如身份認證,如果認證通過表示當前用戶沒有登陸,需要此方法攔截不再向下執行??  ????@Override??  ????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler)?throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor1......preHandle");??  ??????????  ????????//return?false表示攔截,不向下執行??  ????????//return?true表示放行??????????  ????????return?false;??  ????}??  ??????  ????//進入Handler方法之后,返回modelAndView之前執行??  ????//應用場景從modelAndView出發:將公用的模型數據(比如菜單導航)在這里??  ????//傳到視圖,也可以在這里統一指定視圖??  ????@Override??  ????public?void?postHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?ModelAndView?modelAndView)?throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor1......postHandle");??  ??????????  ????}??  ??????  ????//執行Handler完成執行此方法??  ????//應用場景:統一異常處理,統一日志處理??  ????@Override??  ????public?void?afterCompletion(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?Exception?ex)??  ????????????throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor1......afterHandle");??  ??????????  ????}??  }??  
 
HandlerInterceptor2.java:
[java]?view plaincopy package?cn.edu.hpu.ssm.interceptor;??  ??  ??  import?javax.servlet.http.HttpServletRequest;??  import?javax.servlet.http.HttpServletResponse;??  ??  ??  import?org.springframework.web.servlet.HandlerInterceptor;??  import?org.springframework.web.servlet.ModelAndView;??  ??  ??  //測試攔截器2??  public?class?HandlerInterceptor2?implements?HandlerInterceptor{??  ??  ??  ????//執行Handler方法之前執行??  ????//用于身份認證、身份授權??  ????//比如身份認證,如果認證通過表示當前用戶沒有登陸,需要此方法攔截不再向下執行??  ????@Override??  ????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler)?throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor2......preHandle");??  ??????????  ????????//return?false表示攔截,不向下執行??  ????????//return?true表示放行??????????  ????????return?false;??  ????}??  ??????  ????//進入Handler方法之后,返回modelAndView之前執行??  ????//應用場景從modelAndView出發:將公用的模型數據(比如菜單導航)在這里??  ????//傳到視圖,也可以在這里統一指定視圖??  ????@Override??  ????public?void?postHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?ModelAndView?modelAndView)?throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor2......postHandle");??  ??????????  ????}??  ??????  ????//執行Handler完成執行此方法??  ????//應用場景:統一異常處理,統一日志處理??  ????@Override??  ????public?void?afterCompletion(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?Exception?ex)??  ????????????throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor2......afterHandle");??  ??????????  ????}??  }??  
 
3.3兩個攔截器都放行
將preHandle方法的返回值設為true,然后隨便訪問一個controller,控制臺打印一下結果:
[plain]?view plaincopy HandlerInterceptor1...preHandle??  HandlerInterceptor2...preHandle??  ??  HandlerInterceptor2...postHandle??  HandlerInterceptor1...postHandle??  ??  HandlerInterceptor2...afterCompletion??  HandlerInterceptor1...afterCompletion??  
 
總結:
preHandle方法按順序執行,
postHandle和afterCompletion按攔截器配置的逆向順序執行。
 
3.4攔截器1放行,攔截器2不放行
[plain]?view plaincopy HandlerInterceptor1...preHandle??  HandlerInterceptor2...preHandle??  HandlerInterceptor1...afterCompletion??  
 
總結:
攔截器1放行,攔截器2 preHandle才會執行。
攔截器2 preHandle不放行,攔截器2 postHandle和afterCompletion不會執行。
只要有一個攔截器不放行,postHandle不會執行。
 
3.5攔截器1不放行,攔截器2不放行
[plain]?view plaincopy HandlerInterceptor1...preHandle??  
 
攔截器1 preHandle不放行,postHandle和afterCompletion不會執行。
攔截器1 preHandle不放行,攔截器2不執行。
 
4.根據測試結果,對攔截器應用。
 
比如:統一日志處理攔截器,需要該攔截器preHandle一定要放行,且將它放在攔截器鏈接中第一個位置。
 
比如:登陸認證攔截器,放在攔截器鏈接中第一個位置。權限校驗攔截器,放在登陸認證攔截器之后。(因為登陸通過后才校驗權限)
 
5攔截器應用(實現登陸認證)
 
5.1需求
 
(1)用戶請求url
(2)攔截器進行攔截校驗
如果請求的url是公開地址(無需登陸即可訪問的url),讓放行
如果用戶session 不存在跳轉到登陸頁面
如果用戶session存在放行,繼續操作。
 
5.2登陸controller方法
[java]?view plaincopy package?cn.edu.hpu.ssm.controller;??  ??  import?javax.servlet.http.HttpSession;??  ??  import?org.springframework.stereotype.Controller;??  import?org.springframework.web.bind.annotation.RequestMapping;??  ??  @Controller??  public?class?LoginController?{??  ??????  ????//登錄??  ????@RequestMapping("/login")??  ????public?String?login(HttpSession?session,String?username,String?password)throws?Exception{??  ????????//調用serivce進行用戶身份驗證??  ????????//...??  ??????????  ????????//在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";??  ????}??  }??  
 
登錄頁面:
[html]?view plaincopy <%@?page?language="java"?import="java.util.*"?pageEncoding="utf-8"%>??  <%??  String?path?=?request.getContextPath();??  String?basePath?=?request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";??  %>??  ??  ??  <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??  <html>??  ??<head>??  ????<base?href="<%=basePath%>">??  ??????  ????<title>系統登錄</title>??  ??  ??  ??</head>??  ????  ??<body>??  ???<form?action="${pageContext.request.contextPath?}/login.action"?method="post">??  ????用戶賬號:<input?type="text"?name="username"/><br/>??  ????用戶密碼:<input?type="password"?name="password"/><br/>??  ????<input?type="submit"?value="登錄"/>??  ???</form>??  ??</body>??  </html>??  
 
在商品列表那里加入:
[html]?view plaincopy 當前用戶:${username?}|??  <c:if?test="${username!=null?}">??  <a?href="${pageContext.request.contextPath?}/logout.action">退出</a>??  </c:if>??  
 
5.3登陸認證攔截實現
 
5.3.1代碼實現
[java]?view plaincopy package?cn.edu.hpu.ssm.interceptor;??  ??  import?javax.servlet.http.HttpServletRequest;??  import?javax.servlet.http.HttpServletResponse;??  import?javax.servlet.http.HttpSession;??  ??  import?org.springframework.web.servlet.HandlerInterceptor;??  import?org.springframework.web.servlet.ModelAndView;??  ??  //登錄認證的攔截器??  public?class?LoginInterceptor?implements?HandlerInterceptor{??  ??  ????//執行Handler方法之前執行??  ????//用于身份認證、身份授權??  ????//比如身份認證,如果認證通過表示當前用戶沒有登陸,需要此方法攔截不再向下執行??  ????@Override??  ????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表示攔截,不向下執行??  ????????//return?true表示放行??????????  ????????return?false;??  ????}??  ??????  ????//進入Handler方法之后,返回modelAndView之前執行??  ????//應用場景從modelAndView出發:將公用的模型數據(比如菜單導航)在這里??  ????//傳到視圖,也可以在這里統一指定視圖??  ????@Override??  ????public?void?postHandle(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?ModelAndView?modelAndView)?throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor1......postHandle");??  ??????????  ????}??  ??????  ????//執行Handler完成執行此方法??  ????//應用場景:統一異常處理,統一日志處理??  ????@Override??  ????public?void?afterCompletion(HttpServletRequest?request,?HttpServletResponse?response,??  ????????????Object?handler,?Exception?ex)??  ????????????throws?Exception?{??  ??????????  ????????System.out.println("HandlerInterceptor1......afterHandle");??  ??????????  ????}??  }??  
 
5.3.2攔截器配置
springmvc.xml中配置:
[html]?view plaincopy <!--?攔截器?-->??  <mvc:interceptors>??  ????<!--?多個攔截器,順序執行?-->??  ????<!--?登錄認證攔截器?-->??  ????<mvc:interceptor>??  ????????<mvc:mapping?path="/**"/>??  ????????<bean?class="cn.edu.hpu.ssm.interceptor.LoginInterceptor"/>??  ????</mvc:interceptor>??  </mvc:interceptors>??  
 
測試:
輸入商品列表的網址,結果發現被攔截在登錄界面(原因:攔截器沒有檢測到登錄用戶的session,所以判定用戶沒有登錄,沒有權限查看商品列表)
 
 
 
                        
                        
                        1.攔截定義
定義攔截器,實現HandlerInterceptor接口。接口中提供三個方法。
[java]?view plaincopy
2.攔截器配置
2.1針對HandlerMapping配置
springmvc攔截器針對HandlerMapping進行攔截設置,如果在某個HandlerMapping中配置攔截,經過該 HandlerMapping映射成功的handler最終使用該攔截器。
[html]?view plaincopy
2.2類似全局的攔截器
springmvc配置類似全局的攔截器,springmvc框架將配置的類似全局的攔截器注入到每個HandlerMapping中。
[html]?view plaincopy
3.攔截測試
3.1測試需求
測試多個攔截器各各方法執行時機。
3.2編寫兩個攔截
HandlerInterceptor1.java:
[java]?view plaincopy
HandlerInterceptor2.java:
[java]?view plaincopy
3.3兩個攔截器都放行
將preHandle方法的返回值設為true,然后隨便訪問一個controller,控制臺打印一下結果:
[plain]?view plaincopy
總結:
preHandle方法按順序執行,
postHandle和afterCompletion按攔截器配置的逆向順序執行。
3.4攔截器1放行,攔截器2不放行
[plain]?view plaincopy
總結:
攔截器1放行,攔截器2 preHandle才會執行。
攔截器2 preHandle不放行,攔截器2 postHandle和afterCompletion不會執行。
只要有一個攔截器不放行,postHandle不會執行。
3.5攔截器1不放行,攔截器2不放行
[plain]?view plaincopy
攔截器1 preHandle不放行,postHandle和afterCompletion不會執行。
攔截器1 preHandle不放行,攔截器2不執行。
4.根據測試結果,對攔截器應用。
比如:統一日志處理攔截器,需要該攔截器preHandle一定要放行,且將它放在攔截器鏈接中第一個位置。
比如:登陸認證攔截器,放在攔截器鏈接中第一個位置。權限校驗攔截器,放在登陸認證攔截器之后。(因為登陸通過后才校驗權限)
5攔截器應用(實現登陸認證)
5.1需求
(1)用戶請求url
(2)攔截器進行攔截校驗
如果請求的url是公開地址(無需登陸即可訪問的url),讓放行
如果用戶session 不存在跳轉到登陸頁面
如果用戶session存在放行,繼續操作。
5.2登陸controller方法
[java]?view plaincopy
登錄頁面:
[html]?view plaincopy
在商品列表那里加入:
[html]?view plaincopy
5.3登陸認證攔截實現
5.3.1代碼實現
[java]?view plaincopy
5.3.2攔截器配置
springmvc.xml中配置:
[html]?view plaincopy
測試:
輸入商品列表的網址,結果發現被攔截在登錄界面(原因:攔截器沒有檢測到登錄用戶的session,所以判定用戶沒有登錄,沒有權限查看商品列表)
我們輸入賬號(王五)密碼(隨便),發現登錄進去,并且看到了用戶名
 
 
點擊退出再次退回登錄界面,再次輸入商品列表的網址,結果發現依舊被攔截在登錄界面,原因是session已經被清除。
轉載請注明出處:http://blog.csdn.net/acmman/article/details/47680517
總結
以上是生活随笔為你收集整理的springmvc配置拦截器及测试详解的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: spring学习(2):初始化sprin
 - 下一篇: 第十三期:你不想错过的那些JSON工具