【Spring Boot系列】- Spring Boot拦截器

news/2024/11/16 7:31:30/

【Spring Boot系列】- Spring Boot拦截器

文章目录

  • 【Spring Boot系列】- Spring Boot拦截器
    • 一、概述
    • 二、拦截器(Interceptor)定义步骤
      • 2.1 定义拦截器(Interceptor)
      • 2.2 注册拦截器(Interceptor)
      • 2.3 拦截器原理
    • 三、过滤器与拦截器区别
    • 四、拦截器的应用
      • 权限检查
      • 日志记录
      • 性能监控
      • 通用行为

一、概述

拦截器(Interceptor)是在面向切面编程中应用的,就是在service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。可以根据 URL 对请求进行拦截,主要应用于登陆校验、权限验证、乱码解决、性能监控和异常处理等功能。

二、拦截器(Interceptor)定义步骤

在 Spring Boot 项目中,使用拦截器功能通常需要以下 3 步

  1. 定义拦截器
  2. 注册拦截器
  3. 指定拦截规则(如果是拦截所有,静态资源也会被拦截)

2.1 定义拦截器(Interceptor)

定义拦截器十分的简单,只需要创建一个拦截器类,并实现 HandlerInterceptor 接口,重写以下三个方法:

@Slf4j
@Component
public class MyHandleInterceptor implements HandlerInterceptor {/*** 目标方法执行前* 该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作* 返回 true 表示继续向下执行,返回 false 表示中断后续操作*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object loginUser = request.getSession().getAttribute("loginUser");if (loginUser == null) {//未登录,返回登陆页request.setAttribute("msg", "您没有权限进行此操作,请先登陆!");request.getRequestDispatcher("/index.html").forward(request, response);return false;} else {//放行return true;}}/*** 目标方法执行后* 该方法在控制器处理请求方法调用之后、解析视图之前执行* 可以通过此方法对请求域中的模型和视图做进一步修改*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("postHandle执行{}", modelAndView);}/*** 页面渲染后* 该方法在视图渲染结束后执行* 可以通过此方法实现资源清理、记录日志信息等工作*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("afterCompletion执行异常{}", ex);}
}

2.2 注册拦截器(Interceptor)

创建一个实现了 WebMvcConfigurer 接口的配置类(使用了 @Configuration 注解的类),重写 addInterceptors() 方法,并在该方法中调用 registry.addInterceptor() 方法将自定义的拦截器注册到容器中。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {@Resourceprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册自己的拦截器,并设置拦截的请求路径//addPathPatterns为拦截此请求路径的请求//excludePathPatterns为不拦截此路径的请求registry.addInterceptor(MyHandleInterceptor).addPathPatterns("/user/*").excludePathPatterns("/user/login");}
}

2.3 拦截器原理

  1. 根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有 拦截器】;
  2. 先来顺序执行 所有拦截器的 preHandle方法;
    1. 如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle;
    2. 如果当前拦截器返回为false。直接倒序执行所有已经执行了的拦截器的 afterCompletion;
  3. 如果任何一个拦截器返回false。直接跳出不执行目标方法;
  4. 所有拦截器都返回True。执行目标方法;
  5. 倒序执行所有拦截器的postHandle方法;
  6. 前面的步骤有任何异常都会直接倒序触发 afterCompletion;
  7. 页面成功渲染完成以后,也会倒序触发 afterCompletion;

三、过滤器与拦截器区别

  1. 过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
  2. 、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
  3. 过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射。
  4. Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
  5. Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理(反射)的方式来执行。
  6. Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

四、拦截器的应用

是springmvc提供了一个拦截器的机制,它专门用于拦截controller的路由请求。它的本质是:AOP面向切面的编程,也就是说符合横切关注点的功能都可以考虑使用拦截器实现。比如一些应用场景:


http://www.ppmy.cn/news/1010182.html

相关文章

MFC遍历目录包括子目录下所有文件、特定类型文件

文章目录 用法实现遍历所有文件遍历所有txt文件用法 vector<CString> v; //获取所有文件 GetFilePath(v,L"D:\\test\\"); //文件路径储存在容器里面,遍历容器 for(int i=0

go语言使用chan的小技巧

技巧1&#xff1a;关闭某个chan时&#xff0c;所有读取该chan的协程都会收到通知 注意事项&#xff1a;是直接关闭chan就可以了&#xff0c;不需要向这个协程内压入数据&#xff0c;因为压入数据的话最终还得关闭chan 举例&#xff1a;如果协程A希望协程B在处理完某个事情后自…

yolov8在rknn(rv1109/1126)模型转换、量化移植过程

续&#xff1a;rv1109/1126 rknn 模型量化过程_CodingInCV的博客-CSDN博客 Yolov8简介 yolov8是比较新的目标检测模型&#xff0c;根据论文和开源项目的报告&#xff0c;相对使用比较广泛的yolov5提升还比较明显。 yolov8与yolov5相比&#xff0c;结构上的主要区别是将C3结构…

谈谈网络安全

目录 1.概念 2.发展现状 3.主要问题 1.概念 网络安全是指保护计算机网络和其中的数据免受未经授权访问、损坏、窃取或破坏的过程和技术。网络安全涉及预防和检测潜在的威胁和漏洞&#xff0c;并采取措施保护网络的机密性、完整性和可用性。 网络安全的概念包括以下几个方面&am…

每日一题——两数之和

题目 给出一个整型数组 numbers 和一个目标值 target&#xff0c;请在数组中找出两个加起来等于目标值的数的下标&#xff0c;返回的下标按升序排列。 &#xff08;注&#xff1a;返回的数组下标从1开始算起&#xff0c;保证target一定可以由数组里面2个数字相加得到&#xff0…

C++路线(全网20篇高赞文章总结)

为节省时间&#xff0c;可直接跳转到 --> &#x1f33c;干货 目录 &#x1f33c;前言 &#x1f33c;来源 &#x1f416;现状 &#x1f33c;干货 入门阶段 入门项目 学习顺序 &#x1f409;大二打算 &#x1f33c;前言 来源的20篇博客&#xff0c;视频中&#x…

【C++】二叉搜索树的模拟实现

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

neo4j查询语言Cypher详解(二)--Pattern和类型

Patterns 图形模式匹配是Cypher的核心。它是一种用于通过应用声明性模式从图中导航、描述和提取数据的机制。在MATCH子句中&#xff0c;可以使用图模式定义要搜索的数据和要返回的数据。图模式匹配也可以在不使用MATCH子句的情况下在EXISTS、COUNT和COLLECT子查询中使用。 图…