SpringBoot 拦截器(Interceptor)详解

news/2025/2/13 5:54:38/

概念

在Spring Boot中,拦截器是一种用于处理HTTP请求的机制,主要用于执行一些预处理或后处理的逻辑。与AOP不同,拦截器更专注于HTTP请求的处理


拦截器接口

在Spring Boot中,拦截器需要实现HandlerInterceptor接口!!!

//这个接口定义了三个主要的方法
preHandle:在请求处理之前被调用,用于进行一些预处理操作
postHandle:在请求处理之后、视图渲染之前被调用,用于进行一些后处理操作
afterCompletion:在整个请求处理完成后被调用,用于进行一些资源清理操作

配置拦截器

//在Spring Boot中配置拦截器主要通过实现WebMvcConfigurer接口,并覆盖addInterceptors方法
//在上述例子中,MyInterceptor  是实现了HandlerInterceptor接口的拦截器类。通过addPathPatterns指定需要拦截的路径,通过excludePathPatterns指定排除的路径。
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/api/**")  // 拦截的路径.excludePathPatterns("/public/**");  // 排除的路径}
}

 拦截器的实现

拦截器的实现类需要实现HandlerInterceptor接口,并覆盖其中的方法

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前执行的逻辑return true; // 返回true表示继续执行后续操作,返回false表示中断请求处理}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理之后执行的逻辑,视图渲染之前}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在整个请求处理完成后执行的逻辑,包括视图渲染之后}
}

使用场景

拦截器常用于

  • 身份验证
  • 权限控制
  • 日志记录
  • 统一异常处理
  • 请求参数处理

拦截器(Interceptor)和切面(AOP)之间的区别

拦截器

AOP

关注点

拦截器主要关注HTTP请求的处理,通常用于预处理、后处理、日志记录等与HTTP请求相关的操作,拦截器工作在Controller层之上,能够截取请求的生命周期

AOP关注点更加广泛,应用于方法调用、对象的创建、属性的获取等各个方面,AOP更灵活,可以在更细粒度的操作上进行横切关注点的处理

作用范围

拦截器主要作用于HTTP请求处理,对Controller层的处理有直接影响。拦截器的作用范围更集中

AOP可以作用于整个应用程序的多个模块,跨足多个层次。AOP的作用范围更广泛,不仅限于HTTP请求

使用场景

拦截器常用于身份验证、权限控制、日志记录等与HTTP请求生命周期相关的场景

AOP常用于横切关注点,如日志记录、性能监控、事务管理等,AOP更适合处理那些与业务逻辑解耦的横切关注点

实现方式

拦截器 在Spring Boot中通过实现HandlerInterceptor接口来创建拦截器

AOP在Spring中,可以通过配置切面和通知,使用@Aspect注解等方式实现AOP

粒度

拦截器作用于整个请求处理阶段,较为粗粒度

AOP可以根据需要选择切入点,可以是方法调用、对象的创建等,较为细粒度

依赖

拦截器主要依赖于Spring MVC框架,用于处理HTTP请求

AOP可以独立于任何框架使用,不仅限于Spring框架


AOP的功能性

  • 日志记录:可以通过AOP实现在方法调用前后记录日志
  • 事务管理:可以使用AOP确保一组操作在事务的上下文中执行
  • 性能监控: 可以通过AOP监控方法的执行时间等性能指标

拦截器(更适合权限控制)

  • 身份验证和授权: 拦截器可以用于对HTTP请求进行身份验证和授权,例如检查用户是否具有执行某个操作的权限
  • 请求预处理: 可以在拦截器中进行请求的预处理,例如解析请求参数、检查请求头等

拦截器(Interceptor)的实现

示例一

//在Spring Boot中,可以通过实现HandlerInterceptor接口来创建一个拦截器,用于判断请求是否携带了 token
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TokenInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从请求头中获取 tokenString token = request.getHeader("Authorization");// 判断 token 是否存在if (token == null || token.isEmpty()) {// 如果不存在,返回未授权状态码,并终止请求response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return false;}// 如果存在 token,继续处理请求return true;}
}
//在这个例子中,TokenInterceptor 继承了 HandlerInterceptorAdapter 类,重写了 preHandle 方法。
//在 preHandle 方法中,从请求头中获取了名为 "Authorization" 的 token,然后判断是否存在。
//如果不存在,返回未授权状态码(SC_UNAUTHORIZED)并终止请求;如果存在,继续处理请求

接下来,你需要在配置类中注册这个拦截器 

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册拦截器,并设置拦截的路径registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/api/**"); // 设置需要拦截的路径}
}
//在这个例子中,WebMvcConfig 类实现了 WebMvcConfigurer 接口,并覆盖了 addInterceptors 方法,用于注册拦截器。
//在 addInterceptors 方法中,通过 registry.addInterceptor(new TokenInterceptor()) 注册了 TokenInterceptor 拦截器,并使用 .addPathPatterns("/api/**") 指定了需要拦截的路径,可以根据实际需求进行修改

 示例二

//我们再升级一下,需求是在请求前鉴权,如果没有携带 token 则返回 401,在请求后判断逻辑错误返回 500,并在请求完成后输出日志
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TokenInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从请求头中获取 tokenString token = request.getHeader("Authorization");// 判断 token 是否存在if (token == null || token.isEmpty()) {// 如果不存在,返回未授权状态码并终止请求response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return false;}// 在这里可以进行进一步的鉴权逻辑// 如果鉴权失败,可以返回 401 并终止请求// ...return true; // 鉴权通过,继续处理请求}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求处理完成后的逻辑if (ex != null) {// 如果有异常,返回 500 状态码response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);// 这里可以记录日志或进行其他逻辑处理System.err.println("Request completed with error: " + ex.getMessage());} else {// 请求正常完成,可以记录日志或进行其他逻辑处理System.out.println("Request completed successfully");}}
}
//在这个示例中,preHandle 方法用于在请求前进行鉴权,如果没有携带 token 则返回 401,如果鉴权失败可以在这里终止请求
//afterCompletion 方法用于在请求完成后进行逻辑处理,如果有异常则返回 500 并记录错误日志,否则记录请求正常完成的日志。请根据实际需求进行适当的调整。

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

相关文章

力扣模板题:回文链表

请牢记检测回文串的模板 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ bool isPalindrome(struct ListNode* head) {int size0;struct ListNode* pointhead;while(point){size;pointpoint->next;}int arr…

2/22作业

1.按位置插入 void insert_pos(seq_p L,datetype value,int pos) { if(LNULL) { printf("入参为空\n"); return; } if(seq_full(L)) { printf("表已满\n"); return; } if(pos>L->len|…

c#高级-正则表达式

正则表达式是由普通字符和元字符(特殊符号)组成的文字形式 应用场景 1.用于验证输入的邮箱是否合法。 2.用于验证输入的电话号码是否合法。 3.用于验证输入的身份证号码是否合法。等等 正则表达式常用的限定符总结: 几种常用的正则简写表达式…

大数据开发项目--音乐排行榜

环境:windows10,centos7.9,hadoop3.2、hbase2.5.3和zookeeper3.8完全分布式; 环境搭建具体操作请参考以下文章: CentOS7 Hadoop3.X完全分布式环境搭建 Hadoop3.x完全分布式环境搭建Zookeeper和Hbase 1. 集成MapReduce…

JAVA编程题系列——涵盖几乎所有java内容

自己定义一个类,有static属性和构造方法,有构造方法重载,有其他方法(方法有对String类型操作) public class MyClass {// 静态属性public static String staticProperty "Static Property";// 成员变量priv…

外贸支付网站需要加ssl证书吗?

随着全球贸易的发展和互联网的普及,外贸支付网站成为了各地商家进行跨境交易的重要平台。在这样一个需要跨境支付和数据传输的网络环境下,网站安全性和用户数据保护变得尤为重要。而SSL证书作为一种加密技术,可以有效保护网站和用户数据的安全…

【C语言基础】:操作符详解(一)

文章目录 操作符详解1. 操作符的分类2. 二进制和进制转换2.1 什么是二进制、八进制、十进制、十六进制2.1.1 二进制和进制转换2.1.2 二进制转十进制2.2.3 二进制转八进制2.2.4 二进制转十六进制 3. 源码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&…

在MFC对话框中嵌入web网页时事件失效问题

2010-04-20 日志 在MFC对话框中嵌入web网页时,网页初始化中添加事件无效 document.body.onkeydown function () {//onkeydown"keydownbody()" 不能激发alert(event.keyCode);if(event.keyCode 27)//VK_ESCAPE //String.fromcharcode(A);{if (external…