正如本文标题所言,今天我们来聊一聊在JAVA应用系统中如何防止接口重复提交;简单地讲,这其实就是“重复提交”的话题,本文将从以下几个部分展开介绍:
1.“重复提交”简介与造成的后果
2.“防止接口重复提交”的实现思路
3.“防止接口重复提交”的代码实战
1、“重复提交”简介与造成的后果对于“重复提交”,想必各位小伙伴都知晓它的意思,简单的理解,它指的是前端用户在间隔很短的时间周期内对同一个请求URL发起请求,导致前端开发者在很短的时间周期内将同一份数据(请求体)提交到后端相同的接口 多次,最终数据库出现多条主键ID不一样而其他业务数据几乎一毛一样的记录;
仔细研究上述整个过程,会发现如果发起的多次请求的时间间隔足够短,即时间趋向于无穷小 时,其过程可以归为“多线程并发导致并发安全”的问题范畴;而对于“并发安全”的话题,debug早在此前自己录制的课程以及之前的文章中介绍过多次了,在此不再赘述;
上述在对“重复提交”的介绍中隐约也提及它所带来的的后果:
(1)数据库DB出现多条一毛一样的数据记录;
(2)如果重复发起的请求足够多、请求体容量足够大,很可能会给系统接口带来极大的压力,导致其出现“接口不稳定”、“DB负载过高”,严重点甚至可能会出现“系统宕机”的情况;
因此,我们需要在一些很可能会出现“重复提交”的后端接口中加入一些处理机制(附注:前端其实也需要配合一同处理的,其处理方式在本文就不做介绍了~);
2、“防止接口重复提交”的实现思路值得一提的是,绝大部分情况下,只有POST/PUT/DELETE的请求方式才会出现“重复提交”的情况,而对于GET请求方式,只要不是出现人为的意外情况,那么它就具有“幂等性”,谈不上“重复提交”现象的出现,因此,在实际项目中,出现“重复提交”现象比较多的一般是POST请求方式;
而在实际项目开发中,“防止接口重复提交”的实现方式有两类,一类是纯粹的针对请求链接URL的,即防止对同一个URL发起多次请求:此种方式明显粒度过大,容易误伤友军;另一类是针对请求链接URL + 请求体 的,这种方式可以说是比较人性化而且也是比较合理的,而我们在后面要介绍的实现方式正是基于此进行实战的;
为了便于小伙伴理解,接下来我们以“用户在前端提交注册信息”为例,介绍“如何防止接口重复提交”的实现思路,如下图所示为整体的实现思路:
文章插图
从该图中可以得知,如果当前提交的请求URL已经存在于缓存中,且 当前提交的请求体 跟 缓存中该URL对应的请求体一毛一样 且 当前请求URL的时间戳跟上次相同请求URL的时间戳 间隔在8s 内,即代表当前请求属于 “重复提交”;如果这其中有一个条件不成立,则意味着当前请求很有可能是第一次请求,或者已经过了8s时间间隔的 第N次请求了,不属于“重复提交”了 。
3、“防止接口重复提交”的代码实战照着这个思路,接下来我们将采用实际的代码进行实战,其中涉及到的技术:Spring Boot2.0 + 自定义注解 + 拦截器 + 本地缓存(也可以分布式缓存);
(1)首先,需要自定义一个用于加在需要“防止重复提交”的请求方法上 的注解RepeatSubmit,该注解的定义代码很简单,就是一个常规的注解定义,如下代码所示:
@Inherited@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RepeatSubmit {}
之后,是直接创建一个新的控制器SubmitController,并在其中创建一请求方法,用于处理前端用户提交的注册信息 请求,如下代码所示:@RestController@RequestMApping("submit")public class SubmitController extends BaseController{//用户注册@RepeatSubmit@PostMapping("register")public BaseResponse register(@RequestBody RegisterDto dto) throws Exception{BaseResponse response=new BaseResponse(StatusCode.Success);//log.info("用户注册,提交上来的请求信息为:{}",dto);//将用户信息插入到dbresponse.setData(dto);return response;}}
其中,RegisterDto 为自定义的实体类,代码定义如下所示:@Datapublic class RegisterDto implements Serializable{private String userName;private String nickName;private Integer age;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- dead-lock 什么是死锁?如何避免死锁详解
- 大中小型视频监控系统IP地址如何规划?组网方式如何选择?
- 如何自己动手更换运营商宽带光猫,需要注意什么?
- 刀剑收藏价值如何
- 教你如何改善孩子的固执性格
- 房间大了怎么做隔断 房间大如何隔开用空调
- 护发产品如何使用 如何正确使用护发产品
- 现在ktv的发展如何 ktv行业现状
- 空调如何清洗过滤网 柜机空调清洗怎么清洗过滤网
- 碧螺春如何冲泡,如何判断染色碧螺春