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
- 下一篇: s3c2440移植MQTT