• 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. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/**"/>
    4. <bean class="com.itbaizhan.interceptor.MyInterceptor">bean>
    5. mvc:interceptor>
    6. 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. <mvc:interceptors>
    2. <bean class="com.itbaizhan.interceptor.MyInterceptor">bean>
    3. mvc:interceptors>

    ==

    1. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/**"/>
    4. <bean class="com.itbaizhan.interceptor.MyInterceptor">bean>
    5. mvc:interceptor>
    6. mvc:interceptors>

    2.局部拦截器

    如下代码中,在标签中配置指定的区域

    1. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/Student/MyController"/>
    4. <bean class="com.itbaizhan.interceptor.MyInterceptor">bean>
    5. mvc:interceptor>
    6. 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. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/**"/>
    4. <bean class="com.itbaizhan.interceptor.MyInterceptor">bean>
    5. mvc:interceptor>
    6. <mvc:interceptor>
    7. <mvc:mapping path="/**"/>
    8. <bean class="com.itbaizhan.interceptor.MyInterceptor2">bean>
    9. mvc:interceptor>
    10. 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 model = modelAndView.getModel();
    13. Set> entries = model.entrySet();
    14. //遍历model,替换敏感词
    15. for (Map.Entry 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. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/**"/>
    4. <bean class="com.itbaizhan.interceptor.SensitiveWordInterceptor">bean>
    5. mvc:interceptor>
    6. mvc:interceptors>

    4.请求结果:

    拦截之前:

    拦截之后: 

     

    六、知识点整理:

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

    2.在SpringMVC配置文件中,配置拦截器的标签为

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

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

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

  • 相关阅读:
    9+单细胞+实验验证,探讨单基因对癌细胞转移作用的思路方向
    STM32 GPIO工作原理
    10分钟了解数据架构、数据模型
    vs code 添加vue3代码模板方法
    [论文] FRCRN:利用频率递归提升特征表征的单通道语音增强
    CloudCompare
    “凌特杯”通信系统设计大赛,题目解析
    一文读懂,python实现常用的数据编码和对称加密
    谷粒商城10——分布式缓存Redis 分布式锁Redisson SpringCache自定义缓存配置
    ARM32开发——第一盏灯
  • 原文地址:https://blog.csdn.net/m0_51697147/article/details/126648296