Springboot + redis + 注解 + 拦截器来实现接口幂等性校验
mhr18 2024-11-24 18:45 24 浏览 0 评论
来自:简书,作者:wangzaiplus
链接:https://www.jianshu.com/p/6189275403ed
一、概念
幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如:
- 订单接口, 不能多次创建订单
- 支付接口, 重复支付同一笔订单只能扣一次钱
- 支付宝回调接口, 可能会多次回调, 必须处理重复回调
- 普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次
等等
二、常见解决方案
三、本文实现
本文采用第2种方式实现, 即通过redis + token机制实现接口幂等性校验
四、实现思路
为需要保证幂等性的每一次请求创建一个唯一标识token, 先获取token, 并将此token存入redis, 请求接口时, 将此token放到header或者作为请求参数请求接口, 后端接口判断redis中是否存在此token:
- 如果存在, 正常处理业务逻辑, 并从redis中删除此token, 那么, 如果是重复请求, 由于token已被删除, 则不能通过校验, 返回请勿重复操作提示
- 如果不存在, 说明参数不合法或者是重复请求, 返回提示即可
五、项目简介
说明:
本文重点介绍幂等性核心实现, 关于springboot如何集成redis、ServerResponse、ResponseCode等细枝末节不在本文讨论范围之内, 有兴趣的小伙伴可以查看我的Github项目:
https://github.com/wangzaiplus/springboot/tree/wxw
六、代码实现
pom
<!-- Redis-Jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!--lombok 本文用到@Slf4j注解, 也可不引用, 自定义log即可-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
JedisUtil
自定义注解@ApiIdempotent
ApiIdempotentInterceptor拦截器
TokenServiceImpl
TestApplication
OK, 目前为止, 校验代码准备就绪, 接下来测试验证
七、测试验证
1、获取token的控制器TokenController
2、TestController, 注意@ApiIdempotent注解, 在需要幂等性校验的方法上声明此注解即可, 不需要校验的无影响
3、获取token
查看redis
4、测试接口安全性: 利用jmeter测试工具模拟50个并发请求, 将上一步获取到的token作为参数
5、header或参数均不传token, 或者token值为空, 或者token值乱填, 均无法通过校验, 如token值为"abcd"
八、注意点(非常重要)
上图中, 不能单纯的直接删除token而不校验是否删除成功, 会出现并发安全性问题, 因为, 有可能多个线程同时走到第46行, 此时token还未被删除, 所以继续往下执行, 如果不校验jedisUtil.del(token)的删除结果而直接放行, 那么还是会出现重复提交问题, 即使实际上只有一次真正的删除操作, 下面重现一下
稍微修改一下代码:
再次请求
再看看控制台
虽然只有一个真正删除掉token, 但由于没有对删除结果进行校验, 所以还是有并发问题, 因此, 必须校验
九、总结
其实思路很简单, 就是每次请求保证唯一性, 从而保证幂等性, 通过拦截器+注解, 就不用每次请求都写重复代码, 其实也可以利用spring aop实现, 无所谓。
对了,在这里说一下,我目前是在职Java开发,如果你现在正在学习Java,了解Java,渴望成为一名合格的Java开发工程师,在入门学习Java的过程当中缺乏基础入门的视频教程,可以关注并私信我:01。获取。我这里有最新的Java基础全套视频教程。
相关推荐
- Java面试必备八股文(java面试必备八股文pdf下载)
-
Java基础1.Java的特点面向对象平台无关性(JVM实现)健壮性(自动内存管理、异常处理)多线程支持安全性2.Java基本数据类型8种基本类型:整型:byte(1),short(2),in...
- 嵌入式ADC驱动框架:通道控制 + 数据读取全流程剖析
-
一个嵌入式操作系统或驱动框架中的ADC(模拟数字转换器)驱动模块,用于管理ADC通道的配置、读取、启停等功能。以下是对各部分的详细解读:一、基本结构和宏控制#ifdefMR_USING_AD...
- 40亿QQ号,不超过1G内存,如何去重?
-
分享一道网上很火的面试题:40亿QQ号,不超过1G的内存,如何去重?这是一个非常经典的海量数据去重问题,并且做了内存限制,最多只能1GB,本文跟大家探讨一下~~一、常规思路我们日常开发中,如果谈到去重...
- PS各个工具的作用及用法(ps中各个工具的用途及使用方法)
-
PS各个工具的作用及用法1.移动工具,可以对PHOTOSHOP里的图层、照片进行移动。2.选框工具,负责建立形状的选区,可以用来抠图。只有选区内的图像可以修改。(1)矩形选择工具,可以对图像选一个矩形...
- PS中常用图片的格式(ps中常用图片的格式是什么)
-
PhotoshopCC支持多种文件格式,如TIFF、GIF、JPEG等,文件格式决定了图像数据的存储方式以及文件是否与一些应用程序兼容。使用【存储】或者【存储为】命令保存文件时,可以在弹出的对话框...
- 浅析 BMP 位图(bmp位图是什么意思)
-
1、BMP是什么?BMP是Bitmap(位图)的简称,是windows显示图片的基本格式。在windows下,任何格式的图片文件(包括视频播放)都要转化为位图才能显示出来,各种各样格式的图片文件也都...
- ClickHouse在自助行为分析场景的实践应用
-
一、自助分析场景OLAP技术选型1.1背景1.2OLAP选型考量1.3ClickHouse二、高斯平台自助分析场景2.1系统介绍2.2系统架构2.3ClickHouse在高斯平台的业务场景...
- PostgreSQL 模糊查询优化(全模糊、忽略大小写优化)
-
模糊查询是数据库系统中非常常见的一种操作,比如查找用户名、邮件、用户地址、电话等等。我们知道前缀匹配(LIKExx%)是可以走索引的,但是全模糊(LIKE%xx%)就无法走索引,甚至忽略大小写等这...
- Java手写一个bitmap(java怎么写)
-
位图(Bitmap)是一种高效的,使用位来记录数据的结构,多用于存储和操作大量布尔值(通常是true或false)。位图通过使用位(bit)来表示布尔值,从而节省存储空间并提高操作效率。位(Bit):...
- 位图(Bitmap)管理在驱动与资源分配中的应用
-
位图(Bitmap)管理在驱动与资源分配中的应用在驱动开发与资源分配的领域中,高效的资源管理方式至关重要。位图(Bitmap)管理凭借其独特的优势,成为了开发者们手中的得力工具。接下来,让我们深入探究...
- Oracle 11g数据库数据仓库模式与一般事务处理模式
-
在Oracle11g数据库安装过程中,数据仓库模式与一般事务处理模式(OLTP)是针对不同业务场景设计的两种架构方案,其核心区别体现在应用场景、数据结构、性能优化方向等多个维度。以下是具体对比:一...
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)