springboot如何实现接口自动幂等
springboot如何实现接口自动幂等
这篇“springboot如何实现接口自动幂等”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springboot如何实现接口自动幂等”文章吧。
幂等
1.概念:任意多次执行所产生的影响均与一次执行的影响相同。
按照这个含义,最终的含义就是 对数据库的影响只能是一次性的,不能重复处理。如何保证其幂等性,通常有以下手段:
1: 数据库建立唯一性索引,可以保证最终插入数据库的只有一条数据
2: token 机制,每次接口请求前先获取一个 token,然后再下次请求的时候在请求的 header 体中加上这个 token,后台进行验证,如果验证通过删除 token,下次请求再次判断 token
3: 悲观锁或者乐观锁,悲观锁可以保证每次 for update 的时候其他 sql 无法 update 数据 (在数据库引擎是 innodb 的时候, select 的条件必须是唯一索引, 防止锁全表)
4: 先查询后判断,首先通过查询数据库是否存在数据,如果存在证明已经请求过了,直接拒绝该请求,如果没有存在,就证明是第一次进来,直接放行。
redis 实现自动幂等的原理图:
一. 搭建redis的服务Api
1: 首先是搭建 redis 服务器。
2: 引入 springboot 中到的 redis 的 stater,或者 Spring 封装的 jedis 也可以,后面主要用到的 api 就是它的 set 方法和 exists 方法, 这里我们使用 springboot 的封装好的 redisTemplate
代码如下:
/*redis工具类*/@ComponentpublicclassRedisService{@AutowiredprivateRedisTemplateredisTemplate;/***写入缓存*@paramkey*@paramvalue*@return*/publicbooleanset(finalStringkey,Objectvalue){booleanresult=false;try{ValueOperations<Serializable,Object>operations=redisTemplate.opsForValue();operations.set(key,value);result=true;}catch(Exceptione){result=false;e.printStackTrace();}returnresult;}/***写入缓存有效期*@return*/publicbooleansetEx(finalStringkey,Objectvalue,LongexpireTime){booleanresult=false;try{ValueOperations<Serializable,Object>operations=redisTemplate.opsForValue();operations.set(key,value);redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);//有效期result=true;}catch(Exceptione){result=false;e.printStackTrace();}returnresult;}/***判断缓存中是否有对应的value*@paramkey*@return*/publicbooleanexists(finalStringkey){returnredisTemplate.hasKey(key);}/***读取缓存*@paramkey*@return*/publicObjectget(finalStringkey){Objectobj=null;ValueOperations<Serializable,Object>operations=redisTemplate.opsForValue();obj=operations.get(key);returnobj;}/***删除对应的value*@paramkey*@return*/publicbooleanremvoe(finalStringkey){if(exists(key)){Booleandelete=redisTemplate.delete(key);returndelete;}returnfalse;}}
二.自定义 AutoIdempotent
自定义一个注解,定义此注解的主要目的是把它添加在需要实现幂等的方法上,凡是某个方法注解了它,都会实现自动幂等。后台利用反射如果扫描到这个注解,就会处理这个方法实现自动幂等,使用元注解 ElementType.METHOD 表示它只能放在方法上,etentionPolicy.RUNTIME 表示它在运行时
packagecom.yxkj.springboot_redis_interceptor.annotion;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceAutoIdempotent{}
三. token 创建和检验
1.token服务接口
我们新建一个接口,创建 token 服务,里面主要是两个方法,一个用来创建 token,一个用来验证 token。创建 token 主要产生的是一个字符串,检验 token 的话主要是传达 request 对象,为什么要传 request 对象呢?主要作用就是获取 header 里面的 token, 然后检验,通过抛出的 Exception 来获取具体的报错信息返回给前端
publicinterfaceTokenService{/***创建token*@return*/StringcreateToken();/***检验token的合法性*@paramrequest*@return*@throwsException*/booleancheckToken(HttpServletRequestrequest)throwsException;}
2.token 的服务实现类
token 引用了 redis 服务,创建 token 采用随机算法工具类生成随机 uuid 字符串, 然后放入到 redis 中 (为了防止数据的冗余保留, 这里设置过期时间为 10000 秒, 具体可视业务而定),如果放入成功,最后返回这个 token 值。checkToken 方法就是从 header 中获取 token 到值 (如果 header 中拿不到,就从 paramter 中获取),如若不存在, 直接抛出异常。这个异常信息可以被拦截器捕捉到,然后返回给前端。
以上就是关于“springboot如何实现接口自动幂等”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注恰卡编程网行业资讯频道。
推荐阅读
-
vue动态添加删除输入框(springboot vue怎么让数据库显示出来)
springbootvue怎么让数据库显示出来?一般情况下是前端调阅后端接口,来获取到数据库的数据,后端哪里会把数据库的数据整理...
-
springboot实现基于aop的切面日志
本文实例为大家分享了springboot实现基于aop的切面日志的具体代码,供大家参考,具体内容如下通过aop的切面方式实现日志...
-
SpringBoot定时任务功能怎么实现
-
SpringBoot中的@Import注解怎么使用
-
SpringBoot整合Lombok及常见问题怎么解决
-
springboot图片验证码功能模块怎么实现
-
Springboot+SpringSecurity怎么实现图片验证码登录
-
SpringBoot注解的知识点有哪些
SpringBoot注解的知识点有哪些这篇“SpringBoot注...
-
SpringBoot2.x中management.security.enabled=false无效怎么解决
-
springboot怎么禁用某项健康检查
springboot怎么禁用某项健康检查今天小编给大家分享一下sp...