spring boot 使用AOP实现是否已登录检测
前后端分离的开发中,用户http请求应用服务的接口时, 如果要求检测该用户是否已登录。可以实现的方法有多种, 本示例是通过aop 的方式实现,简单有效。
约定:前端http的post 请求
export async function request(url,data) {const config = {method: 'POST',headers: {'Content-Type': 'application/json'},}//每个请求的参数要求附加sessionid, 该sessionid 是登录时生成的const paramsData = Object.assign(data,{sessionid:globalData.sessionID || ''})config.body = JSON.stringify(paramsData)try {const res = await window.fetch(url, config)if(res.status!==200){return {status: res.status,data:{},headers: res.headers,url: res.url,statusText:res.statusText}}return {status: res.status,data:await res.json(),headers: res.headers,url: res.url,}} catch (err) {return {status: 404,data:{},headers: res.headers,url: res.url,statusText:'fetch error:'+err.toString()}}}
1、在pom.xml 引用
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
2、创建插入标记
@Target({ElementType.METHOD}) // 只在对象方法上标记
@Retention(RetentionPolicy.RUNTIME) //运行时反射
public @interface Interceptor {String additionalMessage() default "";
}
3、实现切入类
@Aspect
@Component
@Slf4j
public class LoggingAspect {@Autowiredpublic StringRedisTemplate redisTemplatelocate;private <T> T getSessionID(Object postData,Class<T> clazz){return (T)postData;}@Around("@annotation(Interceptor)") //有标记的地方将实现以下和切入public Object logExecutionTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {//获取切入方法的参数,就是前部请求的json数据Object[] args = proceedingJoinPoint.getArgs();//获取其中的sessionid// requestBase 实体类只有一个参sessionid , 做为其它实体类的父类,用于接收接口上传的参数。RequestBase requestBase=getSessionID(args[0],RequestBase.class);log.info("sessionid:{}",requestBase.getSessionid());//检测该sessionid 是否存在(redis)if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) {//用户未登陆throw new Exception("用户未登陆");}//获取 request 和 responseServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());log.info("request:{}",servletRequestAttributes.getRequest());log.info("response:{}",servletRequestAttributes.getResponse());MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();String className = methodSignature.getDeclaringType().getSimpleName();String methodName = methodSignature.getMethod().getName();Instant startTime = Instant.now();//实行被切入的方法Object result = proceedingJoinPoint.proceed();String additionalMessage = methodSignature.getMethod().getAnnotation(Interceptor.class).additionalMessage();long elapsedTime = Duration.between(startTime, Instant.now()).toMillis();log.info("Class Name: {}, Method Name: {}, Additional Message: {}, Elapsed Time: {}ms",className, methodName, additionalMessage, elapsedTime);log.info("Result: {}", result);return result;}
}
4 建立api接口,在需要检测的方法上加入@Interceptor 就完成切入的检测。
@RestController
@Slf4j
public class ExampleController {@PostMapping("/t1")@Interceptor(additionalMessage = "要求检测登录")@ResponseBodypublic ResponseEntity<RequestBase> getData(@RequestBody DataRequest req) {try {return new ResponseEntity<>(req, HttpStatus.OK);} catch (Exception e) {return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);}}
}
5 实体类
@Data
public class DataRequest extends RequestBase {private String name;
}@Data
public class RequestBase{private String sessionid;
}
该方法只适用于少部分需要检测,而大部份不需要检测的情况下,如果整个包都需要检测的,利用execution方 法实现
@Pointcut("execution(public * com.example.myapp..*.*(..))")
@Aspect
@Component
@Slf4j
public class LoginExecution {@Autowiredpublic StringRedisTemplate redisTemplatelocate;private <T> T getSessionID(Object postData,Class<T> clazz){return (T)postData;}//切入点: com.aop.ttt 下的所有public 方法@Pointcut("execution(public * com.aop.ttt..*.*(..))")public void publicMethods() {}@Around("publicMethods()")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {//获取切入方法的参数,就是前部请求的json数据Object[] args = joinPoint.getArgs();//获取其中的sessionid// requestBase 实体类只有一个参sessionid , 做为其它实体类的父类,用于接收接口上传的参数。RequestBase requestBase=getSessionID(args[0],RequestBase.class);log.info("sessionid:{}",requestBase.getSessionid());//检测该sessionid 是否存在(redis)if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) {//用户未登陆throw new Exception("用户未登陆");}//获取 request 和 responseServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());log.info("request:{}",servletRequestAttributes.getRequest());log.info("response:{}",servletRequestAttributes.getResponse());MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();String className = methodSignature.getDeclaringType().getSimpleName();String methodName = methodSignature.getMethod().getName();Instant startTime = Instant.now();//实行被切入的方法Object result = joinPoint.proceed();long elapsedTime = Duration.between(startTime, Instant.now()).toMillis();log.info("Class Name: {}, Method Name: {}, Elapsed Time: {}ms",className, methodName, elapsedTime);log.info("Result: {}", result);return result;}
}
相关文章:
spring boot 使用AOP实现是否已登录检测
前后端分离的开发中,用户http请求应用服务的接口时, 如果要求检测该用户是否已登录。可以实现的方法有多种, 本示例是通过aop 的方式实现,简单有效。 约定:前端http的post 请求 export async function request(url,data) {const …...
为什么从没有负值的数据中绘制的小提琴图(Violin Plot)会出现负值部分?
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 小提琴图(Violin Plot) 是一种用于展示和比较数据分布的可视化工具。它结合了箱形图(Box Plot)和密度图(Kernel Density Plot)的特…...
有哪几种行为会导致服务器被入侵
导致服务器被入侵的行为有很多种,以下是一些常见的行为: 系统漏洞:服务器操作系统或软件存在漏洞,攻击者可以通过利用这些漏洞获取系统权限,从而入侵服务器。 弱口令:服务器的账号密码过于简单或者未及时更…...
Redis RabbitMQ
Redis:轻量级,NoSQL数据库 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这…...
http 和 https 的区别?
目录 1.http 和 https 的基本概念 2.http 和 https 的区别 3.https 协议的工作原理 4.https 协议的优点 5.https 协议的缺点 1.http 和 https 的基本概念 http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和…...
C++中线程的创建
线程创建 引言为什么要使用线程线程的创建使用函数指针示例运行结果使用类对象示例运行结果使用lambda表达式示例运行结果使用带参数的函数作为线程处理函数示例运行结果使用类成员函数示例运行结果引言 在学习C++的过程中,线程的使用作为一个非常重要的部分,也是在复杂项目…...
基于JavaWeb开发的家政服务平台计算机毕业设计[附源码]
基于JavaWeb开发的家政服务平台计算机毕业设计[附源码] 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统…...
性能调优:容易忽视的JavaScript标签属性及其性能影响
在性能优化中,我们都知道,async属性可以让script标签变得不阻塞HTML解析,defer属性也有类似的功能,但实际defer是会阻塞script解析的(用defer的话,多个script会按顺序执行,而async执行是无序的&…...
【机器学习笔记】7 KNN算法
距离度量 欧氏距离(Euclidean distance) 欧几里得度量(Euclidean Metric)(也称欧氏距离)是一个通常采用的距离定义,指在𝑚维空间中两个点之间的真实距离,或者向量的自然长度(即该点…...
mysql 2-20
TEXT类型 枚举类型 SET类型 二进制字符串类型 BLOB类型 注意事项 JSON类型 提取数据 空间类型 选择建议 约束...
Unity3D Shader 素描风格渲染管线实现详解
前言 在游戏开发中,渲染效果是非常重要的一部分,它可以直接影响游戏的视觉效果和玩家的体验。而素描风格的渲染效果是一种非常独特和有趣的风格,可以为游戏增添一种艺术氛围。在Unity3D中,可以通过编写Shader来实现素描风格的渲染…...
WordPress站点如何实现发布文章即主动推送到百度快速收录和普通收录?
我们在WordPress后台成功发布文章之后,如果靠搜索引擎来抓取的话,可能会比较慢,所以十分有必要将我们成功发布的文章马上提交到百度、必应等搜索引擎中。下面boke112百科就跟大家说一说WordPress站点如何实现发布文章即主动推送到百度快速收录…...
C++11---(3)
目录 一、可变参数模板 1.1、可变参数模板的概念 1.2、可变参数模板的定义方式 1.3、如何获取可变参数 二、lambda表达式 2.1、Lamabda表达式定义 2.2、为什么有Lambda 2.3、Lambda表达式的用法 2.4、函数对象与lambda表达式 三、包装器 3.1、function 3.2、bind …...
【常识】大数据设计基础知识
底层存储:hadoop(hdfsmapreduce) Hadoop已经有十几年的历史,它是大数据领域的存储基石,HDFS目前仍然没有成熟替代品;MapR 文件系统在业内已经具有一定知名度了,不仅 MapR 宣布它自己的文件系统比 HDFS 快2-…...
Vue:Vuex模块化编码(非常实用)
一、情景说明 通过前面的学习,我们知道,Vuex的核心文件就是indexc.js 这个文件里面,主要是四个对象 actions、mutations、state、getters 那么,随着业务的复杂化,所有的逻辑都写在一个actions里面吗? 显然…...
springboot 异步执行方法详细介绍
在Spring Boot中,异步执行方法是一种提高应用程序性能和响应性的技术。通过异步执行,你可以在处理耗时的业务逻辑时,不需要阻塞当前线程,从而提高应用程序的吞吐量和并发处理能力。 基本概念 在Spring中ÿ…...
拿捏c语言指针(下)
前言 此篇讲解的主要是函数与指针的那些事~ 书接上回 拿捏c语言指针(上)和 拿捏c语言指针(中) 没有看的小伙伴要抓紧喽~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误&#x…...
Spring源码笔记之SpringIOC--(3)什么是BeanFactory?
什么是BeanFactory? BeanFactory是SpringIOC的最顶层接口,涵盖了IOC容器最基本的操作。ListableBeanFactory、ConfigurableBeanFactory提供了IOC容器获取所有Bean、配置Bean的额外能力。所有BeanFactory的实现类持有所有Bean的定义BeanDefinition&#…...
微信小程序之会议OA个人中心后台交互
目录 获取用户昵称头像和昵称 小程序登录 登录-小程序 wx.checkSession wx.login wx.request 后台 准备数据表 反向生成工具生成 准备封装前端传过来的数据 小程序服器配置 导入微信小程序SDK application.yml WxProperties WxConfig WxAuthController 登录-小…...
代码随想录算法训练营第52天(动态规划09 ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III
动态规划part09 198.打家劫舍解题思路 213.打家劫舍II解题思路 337.打家劫舍III解题思路 今天就是打家劫舍的一天,这个系列不算难,大家可以一口气拿下。 198.打家劫舍 题目链接: 198.打家劫舍 视频讲解: 198.打家劫舍 文章讲解&…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
