当前位置:   article > 正文

07 SpringMVC 拦截器_微服务项目使用拦截器

微服务项目使用拦截器

目录

一、SpringMVC 拦截器_拦截器简介

二、SpringMVC 拦截器_拦截器使用

三、SpringMVC 拦截器_拦截器作用域

四、SpringMVC 拦截器_拦截器链与执行顺序

五、SpringMVC 拦截器_拦截器过滤敏感词案例

六、知识点整理:


一、SpringMVC 拦截器_拦截器简介

 SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。

拦截器和过滤器的区别:

1.拦截器是SpringMVC组件,而过滤器是Servlet组件。

2.拦截器不依赖Web容器,过滤器依赖Web容器。

3.拦截器只能对控制器请求起作用,而过滤器可以对所有的请求起作用。

4.拦截器可以直接获取IOC容器中的对象,而过滤器不太方便获取。

二、SpringMVC 拦截器_拦截器使用

项目结构:

1.使用Maven创建SpringMVC的Web项目

2.创建控制器方法MyController1

  1. @Controller
  2. public class MyController1 {
  3. @RequestMapping("/m1")
  4. public String m1(){
  5. System.out.println("控制器方法m1");
  6. return "result";
  7. }
  8. }

3.创建拦截器类MyInterceptor,该类实现HandlerInterceptor接口,需要重写三个方法:

(1)preHandle:请求到达Controller前执行的方法,返回值为true时,请求可以通过拦截器,返回值为false时,请求不能通过拦截器,即被拦截器拦截

(2)postHandle:跳转到JSP前执行的方法

3)afterCompletion:跳转到JSP执行后的方法

  1. public class MyInterceptor implements HandlerInterceptor {
  2. //请求到达Controller前执行
  3. @Override
  4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. System.out.println("拦截器1:请求到达Controller前");
  6. return false;
  7. }
  8. //跳转到JSP页面前执行,此时可以向request域添加数据,也就是这里的name可以传到request域中
  9. @Override
  10. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  11. System.out.println("拦截器1:跳转到JSP页面前");
  12. request.setAttribute("name","坏蛋");
  13. }
  14. //跳转到JSP页面后执行,此时不能向request域添加数据,也就是这里的age传不到request域中
  15. @Override
  16. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  17. System.out.println("拦截器1:跳转到JSP页面后");
  18. request.setAttribute("age",10);
  19. }
  20. }

4.编写JSP页面 result.jsp

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>结果</title>
  5. </head>
  6. <body>
  7. <h3>name:${requestScope.name}</h3>
  8. <h3>age:${requestScope.age}</h3>
  9. </body>
  10. </html>

5.SpringMVC核心配置文件springmvc.xml中配置拦截器

  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 配置拦截器的作用路径,/**表示作用于所有控制器-->
  5. <mvc:mapping path="/**"/>
  6. <!-- 配置拦截器对象,指定用哪个拦截器-->
  7. <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
  8. </mvc:interceptor>
  9. </mvc:interceptors>

6.请求结果:

1.当 preHandle方法返回值为false时 :

当preHandle方法返回值为false时,请求会被拦截器拦截,不会到达Controller控制器。

2.当 preHandle方法返回值为true时 :

 

 由结果可以看出,当preHandle方法返回值为true时,请求可以通过拦截器,不会被拦截器拦截,所以先执行preHandle方法,然后到达Controller层执行方法,再跳转到JSP页面,在跳转到JSP页面前先执行postHandle,等到JSP页面执行完毕再执行afterCompletion方法。同时,PostHandle方法在JSP页面前执行,所以可以向request域中添加数据,而afterCompletion方法在JSP页面执行后执行,所以不能向request域中添加数据。

三、SpringMVC 拦截器_拦截器作用域

1.全局拦截器

全局拦截器可以拦截所有控制器处理的URL,作用等于/** 配置方式如下:
  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <!-- 全局拦截器-->
  4. <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
  5. </mvc:interceptors>

==

  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 配置拦截器的作用路径,/**表示作用于所有控制器-->
  5. <mvc:mapping path="/**"/>
  6. <!-- 配置拦截器对象,指定用哪个拦截器-->
  7. <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
  8. </mvc:interceptor>
  9. </mvc:interceptors>

2.局部拦截器

如下代码中,在<mvc:mapping path="">标签中配置指定的区域

  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 配置拦截器的作用路径,/**表示作用于所有控制器-->
  5. <mvc:mapping path="/Student/MyController"/>
  6. <!-- 配置拦截器对象,指定用哪个拦截器-->
  7. <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
  8. </mvc:interceptor>
  9. </mvc:interceptors>

四、SpringMVC 拦截器_拦截器链与执行顺序

 如果一个URL能够被多个拦截器所拦截,全局拦截器最先执行,其他拦截器根据配置文件中配置的从上到下执行,如上图,先执行拦截器1,再执行拦截器2,再执行Handler控制器,然后返回去先执行postHandle2-->postHandle1-->afterCompletion2-->afterCompletion1

1.编写拦截器类MyInterceptor2

  1. public class MyInterceptor implements HandlerInterceptor {
  2. //请求到达Controller前执行
  3. @Override
  4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. System.out.println("拦截器1:请求到达Controller前");
  6. return true;
  7. }
  8. //跳转到JSP页面前执行,此时可以向request域添加数据,也就是这里的name可以传到request域中
  9. @Override
  10. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  11. System.out.println("拦截器1:跳转到JSP页面前");
  12. // request.setAttribute("name","坏蛋");
  13. }
  14. //跳转到JSP页面后执行,此时不能向request域添加数据,也就是这里的age传不到request域中
  15. @Override
  16. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  17. System.out.println("拦截器1:跳转到JSP页面后");
  18. // request.setAttribute("age",10);
  19. }
  20. }
  1. public class MyInterceptor implements HandlerInterceptor {
  2. //请求到达Controller前执行
  3. @Override
  4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. System.out.println("拦截器1:请求到达Controller前");
  6. return true;
  7. }
  8. //跳转到JSP页面前执行,此时可以向request域添加数据,也就是这里的name可以传到request域中
  9. @Override
  10. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  11. System.out.println("拦截器1:跳转到JSP页面前");
  12. // request.setAttribute("name","坏蛋");
  13. }
  14. //跳转到JSP页面后执行,此时不能向request域添加数据,也就是这里的age传不到request域中
  15. @Override
  16. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  17. System.out.println("拦截器1:跳转到JSP页面后");
  18. // request.setAttribute("age",10);
  19. }
  20. }

2.在springmvc核心配置文件springmvc.xml中配置拦截器链

  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <!-- 拦截器1 -->
  4. <mvc:interceptor>
  5. <!-- 配置拦截器的作用路径,/**表示作用于所有控制器-->
  6. <mvc:mapping path="/**"/>
  7. <!-- 配置拦截器对象,指定用哪个拦截器-->
  8. <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
  9. </mvc:interceptor>
  10. <!-- 拦截器2 -->
  11. <mvc:interceptor>
  12. <!-- 配置拦截器的作用路径,/**表示作用于所有控制器-->
  13. <mvc:mapping path="/**"/>
  14. <!-- 配置拦截器对象,指定用哪个拦截器-->
  15. <bean class="com.itbaizhan.interceptor.MyInterceptor2"></bean>
  16. </mvc:interceptor>
  17. </mvc:interceptors>

3.请求结果:

 1.当MyInterceptor、MyInterceptor2中的preHandle方法返回值同时为true时,preHandle()方法顺序执行,postHandle()、afterCompletion()方法逆序执行。

拦截器执行顺序:

preHandle1()-->preHandle2()-->Handler-->postHandle1()-->postHandle2()-->afterCompletion1()-->afterCompletion2()

 2. 当MyInterceptor中的preHandle方法返回值为false,MyInterceptor2中的preHandle方法返回值为true时, 在preHandle1()后面的preHandle()、postHandle()都不会执行。

拦截器执行顺序:

preHandle1()拦截,无后续;

3.当MyInterceptor中的preHandle方法返回值为true,MyInterceptor2中的preHandle方法返回值为false时,拦截器1、拦截器2的preHandle()都会执行,但Handler和postHandle()不会执行,同时afterCompletion()只执行对应preHandle()方法返回值为true拦截器。

拦截器执行顺序:

preHandle1()-->preHandle2()-->afterCompletion1()

结论:

当有多个拦截器对同一个作用域进行拦截时:

1.preHandle()方法顺序执行,postHandle()、afterCompletion()方法逆序执行。

2.只要有一个preHandle()拦截,在它之后的preHandle()、postHandle()都不会执行。

3.只要相应的preHandle()放行,对应的afterCompletion()就会执行。

五、SpringMVC 拦截器_拦截器过滤敏感词案例

 在系统中,我们需要将所有响应中的一些敏感词替换为 *** ,此时可以使用拦截器达到要求:

1.编写控制器方法MyController2

  1. @Controller
  2. public class MyController2 {
  3. @RequestMapping("/m2")
  4. public String m2(Model model){
  5. model.addAttribute("name","大笨蛋");
  6. return "result";
  7. }
  8. }

2.编写敏感词拦截器SensitiveWordInterceptor

  1. //敏感词拦截器
  2. public class SensitiveWordInterceptor implements HandlerInterceptor {
  3. @Override
  4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. return true;
  6. }
  7. @Override
  8. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  9. //定义敏感词列表
  10. String[] sensitiveWords = {"坏人","笨蛋","暴力"};
  11. //获取Model中的所有数据
  12. Map<String, Object> model = modelAndView.getModel();
  13. Set<Map.Entry<String, Object>> entries = model.entrySet();
  14. //遍历model,替换敏感词
  15. for (Map.Entry<String, Object> entry : entries) {
  16. String key = entry.getKey();
  17. String value = entry.getValue().toString();
  18. //将model值和敏感词列表遍历比对
  19. for (String sensitiveWord:sensitiveWords){
  20. //只要数据模型的值包含敏感词,替换
  21. if (value.contains(sensitiveWord)){
  22. String newStr = value.replaceAll(sensitiveWord,"***");
  23. model.put(key,newStr);
  24. }
  25. }
  26. }
  27. }
  28. }

3.在springmvc核心配置文件springmvc.xml中配置拦截器链

  1. <!-- 配置拦截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <!-- 敏感词拦截器-->
  5. <!-- 配置拦截器的作用路径,/**表示作用于所有控制器-->
  6. <mvc:mapping path="/**"/>
  7. <!-- 配置拦截器对象,指定用哪个拦截器-->
  8. <bean class="com.itbaizhan.interceptor.SensitiveWordInterceptor"></bean>
  9. </mvc:interceptor>
  10. </mvc:interceptors>

4.请求结果:

拦截之前:

拦截之后: 

 

六、知识点整理:

1.SpringMVC中,定义拦截器需要实现HandlerInterceptor 接口

2.在SpringMVC配置文件中,配置拦截器的标签为<mvc:interceptor>

3.在SpringMVC中,全局拦截器会拦截“所有控制器处理的URL”

4.SpringMVC中,拦截器链的执行顺序为preHandle() 顺序执行, postHandle() 、afterCompletion()逆序执行。”

5.在SpringMVC中,只要相应的 preHandle() 放行,afterComletion() 就会执行。”

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

闽ICP备14008679号