当前位置:   article > 正文

【SpringMVC整合MyBatis】springmvc拦截器-定义和配置_springmvc mybatis拦截器

springmvc mybatis拦截器
拦截器
1.拦截定义

定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。
  1. package cn.edu.hpu.ssm.interceptor;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.web.servlet.HandlerInterceptor;
  5. import org.springframework.web.servlet.ModelAndView;
  6. //测试拦截器1
  7. public class HandlerInterceptor1 implements HandlerInterceptor{
  8. //执行Handler方法之前执行
  9. //用于身份认证、身份授权
  10. //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
  11. @Override
  12. public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
  13. Object handler) throws Exception {
  14. //return false表示拦截,不向下执行
  15. //return true表示放行
  16. return false;
  17. }
  18. //进入Handler方法之后,返回modelAndView之前执行
  19. //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里
  20. //传到视图,也可以在这里统一指定视图
  21. @Override
  22. public void postHandle(HttpServletRequest request, HttpServletResponse response,
  23. Object handler, ModelAndView modelAndView) throws Exception {
  24. }
  25. //执行Handler完成执行此方法
  26. //应用场景:统一异常处理,统一日志处理
  27. @Override
  28. public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
  29. Object handler, Exception ex)
  30. throws Exception {
  31. }
  32. }

2.拦截器配置
2.1针对HandlerMapping配置
springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。
  1. <bean
  2. class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
  3. <property name="interceptors">
  4. <list>
  5. <ref bean="handlerInterceptor1"/>
  6. <ref bean="handlerInterceptor2"/>
  7. </list>
  8. </property>
  9. </bean>
  10. <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
  11. <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
一般不推荐使用。


2.2类似全局的拦截器
springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。
  1. <!-- 拦截器 -->
  2. <mvc:interceptors>
  3. <!-- 多个拦截器,顺序执行 -->
  4. <mvc:interceptor>
  5. <!-- /**表示所有url包括子url路径 -->
  6. <mvc:mapping path="/**"/>
  7. <bean class="cn.edu.hpu.ssm.interceptor.HandlerInterceptor1"/>
  8. </mvc:interceptor>
  9. <mvc:interceptor>
  10. <mvc:mapping path="/**"/>
  11. <bean class="cn.edu.hpu.ssm.interceptor.HandlerInterceptor2"/>
  12. </mvc:interceptor>
  13. </mvc:interceptors>

3.拦截测试
3.1测试需求
测试多个拦截器各各方法执行时机。

3.2编写两个拦截
HandlerInterceptor1.java:
  1. package cn.edu.hpu.ssm.interceptor;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.web.servlet.HandlerInterceptor;
  5. import org.springframework.web.servlet.ModelAndView;
  6. //测试拦截器1
  7. public class HandlerInterceptor1 implements HandlerInterceptor{
  8. //执行Handler方法之前执行
  9. //用于身份认证、身份授权
  10. //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
  11. @Override
  12. public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
  13. Object handler) throws Exception {
  14. System.out.println("HandlerInterceptor1......preHandle");
  15. //return false表示拦截,不向下执行
  16. //return true表示放行
  17. return false;
  18. }
  19. //进入Handler方法之后,返回modelAndView之前执行
  20. //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里
  21. //传到视图,也可以在这里统一指定视图
  22. @Override
  23. public void postHandle(HttpServletRequest request, HttpServletResponse response,
  24. Object handler, ModelAndView modelAndView) throws Exception {
  25. System.out.println("HandlerInterceptor1......postHandle");
  26. }
  27. //执行Handler完成执行此方法
  28. //应用场景:统一异常处理,统一日志处理
  29. @Override
  30. public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
  31. Object handler, Exception ex)
  32. throws Exception {
  33. System.out.println("HandlerInterceptor1......afterHandle");
  34. }
  35. }

HandlerInterceptor2.java:
  1. package cn.edu.hpu.ssm.interceptor;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.web.servlet.HandlerInterceptor;
  5. import org.springframework.web.servlet.ModelAndView;
  6. //测试拦截器2
  7. public class HandlerInterceptor2 implements HandlerInterceptor{
  8. //执行Handler方法之前执行
  9. //用于身份认证、身份授权
  10. //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
  11. @Override
  12. public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
  13. Object handler) throws Exception {
  14. System.out.println("HandlerInterceptor2......preHandle");
  15. //return false表示拦截,不向下执行
  16. //return true表示放行
  17. return false;
  18. }
  19. //进入Handler方法之后,返回modelAndView之前执行
  20. //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里
  21. //传到视图,也可以在这里统一指定视图
  22. @Override
  23. public void postHandle(HttpServletRequest request, HttpServletResponse response,
  24. Object handler, ModelAndView modelAndView) throws Exception {
  25. System.out.println("HandlerInterceptor2......postHandle");
  26. }
  27. //执行Handler完成执行此方法
  28. //应用场景:统一异常处理,统一日志处理
  29. @Override
  30. public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
  31. Object handler, Exception ex)
  32. throws Exception {
  33. System.out.println("HandlerInterceptor2......afterHandle");
  34. }
  35. }

3.3两个拦截器都放行
将preHandle方法的返回值设为true,然后随便访问一个controller,控制台打印一下结果:
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle

HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle

HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion

总结:
preHandle方法按顺序执行,
postHandle和afterCompletion按拦截器配置的逆向顺序执行。

3.4拦截器1放行,拦截器2不放行
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion

总结:
拦截器1放行,拦截器2 preHandle才会执行。
拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
只要有一个拦截器不放行,postHandle不会执行。

3.5拦截器1不放行,拦截器2不放行
HandlerInterceptor1...preHandle

拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。
拦截器1 preHandle不放行,拦截器2不执行。

4.根据测试结果,对拦截器应用。

比如:统一日志处理拦截器,需要该拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。

比如:登陆认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过后才校验权限)

5拦截器应用(实现登陆认证)

5.1需求

(1)用户请求url
(2)拦截器进行拦截校验
如果请求的url是公开地址(无需登陆即可访问的url),让放行
如果用户session 不存在跳转到登陆页面
如果用户session存在放行,继续操作。

5.2登陆controller方法
  1. package cn.edu.hpu.ssm.controller;
  2. import javax.servlet.http.HttpSession;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. @Controller
  6. public class LoginController {
  7. //登录
  8. @RequestMapping("/login")
  9. public String login(HttpSession session,String username,String password)throws Exception{
  10. //调用serivce进行用户身份验证
  11. //...
  12. //在session中保存用户身份信息
  13. session.setAttribute("username", username);
  14. //重定向到商品列表界面
  15. return "redirect:/items/queryItems.action";
  16. }
  17. //退出
  18. @RequestMapping("/logout")
  19. public String logout(HttpSession session)throws Exception{
  20. //清除session
  21. session.invalidate();
  22. //重定向到商品列表界面
  23. return "redirect:items/queryItems.action";
  24. }
  25. }

登录页面:
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
  2. <%
  3. String path = request.getContextPath();
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  5. %>
  6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  7. <html>
  8. <head>
  9. <base href="<%=basePath%>">
  10. <title>系统登录</title>
  11. </head>
  12. <body>
  13. <form action="${pageContext.request.contextPath }/login.action" method="post">
  14. 用户账号:<input type="text" name="username"/><br/>
  15. 用户密码:<input type="password" name="password"/><br/>
  16. <input type="submit" value="登录"/>
  17. </form>
  18. </body>
  19. </html>

在商品列表那里加入:
  1. 当前用户:${username }|
  2. <c:if test="${username!=null }">
  3. <a href="${pageContext.request.contextPath }/logout.action">退出</a>
  4. </c:if>

5.3登陆认证拦截实现

5.3.1代码实现
  1. package cn.edu.hpu.ssm.interceptor;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import javax.servlet.http.HttpSession;
  5. import org.springframework.web.servlet.HandlerInterceptor;
  6. import org.springframework.web.servlet.ModelAndView;
  7. //登录认证的拦截器
  8. public class LoginInterceptor implements HandlerInterceptor{
  9. //执行Handler方法之前执行
  10. //用于身份认证、身份授权
  11. //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
  12. @Override
  13. public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
  14. Object handler) throws Exception {
  15. //获取请求的url
  16. String url=request.getRequestURI();
  17. //判断url是否是公开地址(实际使用时将公开地址配置到配置文件中)
  18. if(url.indexOf("login.action")>=0){
  19. //如果要进行登录提交,放行
  20. return true;
  21. }
  22. //判断session
  23. HttpSession session=request.getSession();
  24. //从session中取出用户份信息
  25. String username=(String)session.getAttribute("username");
  26. if(username!=null){
  27. //身份存在,放行
  28. return true;
  29. }
  30. //执行这里表示用户身份需要验证,跳转到登录界面
  31. request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
  32. //return false表示拦截,不向下执行
  33. //return true表示放行
  34. return false;
  35. }
  36. //进入Handler方法之后,返回modelAndView之前执行
  37. //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里
  38. //传到视图,也可以在这里统一指定视图
  39. @Override
  40. public void postHandle(HttpServletRequest request, HttpServletResponse response,
  41. Object handler, ModelAndView modelAndView) throws Exception {
  42. System.out.println("HandlerInterceptor1......postHandle");
  43. }
  44. //执行Handler完成执行此方法
  45. //应用场景:统一异常处理,统一日志处理
  46. @Override
  47. public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
  48. Object handler, Exception ex)
  49. throws Exception {
  50. System.out.println("HandlerInterceptor1......afterHandle");
  51. }
  52. }

5.3.2拦截器配置
springmvc.xml中配置:
  1. <!-- 拦截器 -->
  2. <mvc:interceptors>
  3. <!-- 多个拦截器,顺序执行 -->
  4. <!-- 登录认证拦截器 -->
  5. <mvc:interceptor>
  6. <mvc:mapping path="/**"/>
  7. <bean class="cn.edu.hpu.ssm.interceptor.LoginInterceptor"/>
  8. </mvc:interceptor>
  9. </mvc:interceptors>

测试:
输入商品列表的网址,结果发现被拦截在登录界面(原因:拦截器没有检测到登录用户的session,所以判定用户没有登录,没有权限查看商品列表)


我们输入账号(王五)密码(随便),发现登录进去,并且看到了用户名


点击退出再次退回登录界面,再次输入商品列表的网址,结果发现依旧被拦截在登录界面,原因是session已经被清除。

转载请注明出处:http://blog.csdn.net/acmman/article/details/47680517

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/892577
推荐阅读
相关标签
  

闽ICP备14008679号