精华内容
下载资源
问答
  • 2020-06-30 13:56:27

      最近在开发的过程中遇到前端没有对提交按钮做点击后变灰处理,必须在后端添加防止重复提交的校验。网上有很多中方案,我这边采用的是aop+自定义注解方式实现。
      刚开始采用利用自定义注解+aop+redis防止重复提交这篇博客的逻辑去实现,但是后来在测试多线程访问的时候会出现问题,然后参考网上Redis分布式锁的逻辑,多线程情况下测试只有一个可以通过。参考了LockManager中关于加锁的逻辑。具体的代码逻辑就不占了,只是在上面介绍的资料基础上做了稍微的改造。

    参考资料
    https://blog.csdn.net/weixin_37505014/article/details/103461741
    https://gitee.com/billion/redisLock/

    更多相关内容
  • Java怎样防止重复提交

    2020-12-22 17:08:54
    防止重复提交java解决  B/S结构的软件开发中,特别是在越大型的分布式应用中体现的越明显,后端的处理往往会因为出现较多的时间消耗而引起延迟,这种延迟有可能过长而终使用户认为是自己的操作错误,导致他们重新...
  • 干货实战~Java如何防止接口重复提交

    千次阅读 2021-02-12 22:01:19
    正如本文标题所言,今天我们来聊一聊在Java应用系统中如何防止接口重复提交;简单地讲,这其实就是“重复提交”的话题,本文将从以下几个部分展开介绍:“重复提交”简介与造成的后果“防止接口重复提交”的实现思路...

    正如本文标题所言,今天我们来聊一聊在Java应用系统中如何防止接口重复提交;简单地讲,这其实就是“重复提交”的话题,本文将从以下几个部分展开介绍:“重复提交”简介与造成的后果

    “防止接口重复提交”的实现思路

    “防止接口重复提交”的代码实战8b22ab26ef493287a87a82da4f4b89c6.png

    1、“重复提交”简介与造成的后果

    对于“重复提交”,想必各位小伙伴都知晓它的意思,简单的理解,它指的是前端用户在间隔很短的时间周期内对同一个请求URL发起请求,导致前端开发者在很短的时间周期内将同一份数据(请求体)提交到后端相同的接口 多次,最终数据库出现多条主键ID不一样而其他业务数据几乎一毛一样的记录;

    仔细研究上述整个过程,会发现如果发起的多次请求的时间间隔足够短,即时间趋向于无穷小 时,其过程可以归为“多线程并发导致并发安全”的问题范畴;而对于“并发安全”的话题,debug早在此前自己录制的课程以及之前的文章中介绍过多次了,在此不再赘述;

    上述在对“重复提交”的介绍中隐约也提及它所带来的的后果:

    (1)数据库DB出现多条一毛一样的数据记录;

    (2)如果重复发起的请求足够多、请求体容量足够大,很可能会给系统接口带来极大的压力,导致其出现“接口不稳定”、“DB负载过高”,严重点甚至可能会出现“系统宕机”的情况;

    因此,我们需要在一些很可能会出现“重复提交”的后端接口中加入一些处理机制(附注:前端其实也需要配合一同处理的,其处理方式在本文就不做介绍了~);8b22ab26ef493287a87a82da4f4b89c6.png

    2、“防止接口重复提交”的实现思路

    值得一提的是,绝大部分情况下,只有POST/PUT/DELETE的请求方式才会出现“重复提交”的情况,而对于GET请求方式,只要不是出现人为的意外情况,那么它就具有“幂等性”,谈不上“重复提交”现象的出现,因此,在实际项目中,出现“重复提交”现象比较多的一般是POST请求方式;

    而在实际项目开发中,“防止接口重复提交”的实现方式有两类,一类是纯粹的针对请求链接URL的,即防止对同一个URL发起多次请求:此种方式明显粒度过大,容易误伤友军;另一类是针对请求链接URL + 请求体 的,这种方式可以说是比较人性化而且也是比较合理的,而我们在后面要介绍的实现方式正是基于此进行实战的;

    为了便于小伙伴理解,接下来我们以“用户在前端提交注册信息”为例,介绍“如何防止接口重复提交”的实现思路,如下图所示为整体的实现思路:6887f65f8e1d3dad757f780efad35794.png

    从该图中可以得知,如果当前提交的请求URL已经存在于缓存中,且 当前提交的请求体 跟 缓存中该URL对应的请求体一毛一样 且 当前请求URL的时间戳跟上次相同请求URL的时间戳 间隔在8s 内,即代表当前请求属于 “重复提交”;如果这其中有一个条件不成立,则意味着当前请求很有可能是第一次请求,或者已经过了8s时间间隔的 第N次请求了,不属于“重复提交”了。8b22ab26ef493287a87a82da4f4b89c6.png

    3、“防止接口重复提交”的代码实战

    照着这个思路,接下来我们将采用实际的代码进行实战,其中涉及到的技术:Spring Boot2.0 + 自定义注解 + 拦截器 + 本地缓存(也可以分布式缓存);

    (1)首先,需要自定义一个用于加在需要“防止重复提交”的请求方法上 的注解RepeatSubmit,该注解的定义代码很简单,就是一个常规的注解定义,如下代码所示:45f1283d14e94f49593473bdb2dfd257.png

    之后,是直接创建一个新的控制器SubmitController,并在其中创建一请求方法,用于处理前端用户提交的注册信息 请求,如下代码所示:93148cd31ab82bfb41c5915a60f3fa5f.png

    其中,RegisterDto 为自定义的实体类,代码定义如下所示:e79e6f27789ace742d8f1e30f5634a07.png

    (2)将注解加上去之后,接下来需要自定义一个拦截器RepeatSubmitInterceptor,用于拦截并获取 加了上述这个注解的所有请求方法的相关信息,包括其请求URL和请求体数据,其核心代码如下所示:4b4fd547311cbe5dab68d31cc1e752b6.png

    在这里我们将其定义为抽象类,并自定义一个抽象方法:“判断当前请求是否为重复提交isRepeatSubmit()”,之所以这样做,是因为“判断是否重复提交”可以有多种实现方式,而每种实现方式可以通过继承该抽象类 并 实现该抽象方法 从而将其区分开来,某种程度降低了耦合性(面向接口/抽象类编程);如下代码所示为该抽象类的其中一种实现方式:84d336458a6a910625c4bc8f6e1259de.png

    f643be2ad46a8acac986c43d1f713516.png

    91473446cd39548a0fe4fcd14f08bb93.png

    该代码虽然看起来有点多,但是仔细研读,会发现其实这些代码 就是笔者在上文中贴出的实现流程图 的具体实现,可以说是将理论知识进行真正的落地实现;

    在这里再重复赘述一下,其整体的实现思路为:获取当前请求的URL作为键Key,暂且标记为:A1,其取值为映射Map(Map里面的元素由:请求的链接url 、 请求体的数据、和 请求时的时间戳 三部分组成) 暂且标记为V1;从缓存中(本地缓存或者分布式缓存)查找Key=A1的值V2,如果V2和V1里的请求体数据一样 且 两次请求是在8s内,即代表当前请求是重复提交的,系统将拒绝执行后续的业务逻辑;否则可以继续往后面执行 “将用户信息插入到数据库中” 的业务逻辑;

    (3)最后,需要将上述自定义的拦截器加入中系统全局配置中,如下所示:338ebb7966fd78adbe22e14990da6da3.png

    运行项目,打开Postman,连续多番进行测试,如下几张图所示:37b359349f0af781c832e356a18b978d.png

    67e29b4e48899ccfc33ad793ac5c71d5.png

    713eca2a3baa2d03b2ebe1d6141dc228.png

    至此,我们已经采用实际的代码实战实现了“如何防止接口重复提交”的功能,值得一提的是,上述代码在实现过程中,其核心在于缓存组件的搭建;在“重复提交”这一业务场景中,它需要满足两个条件方可发挥作用:一个是可以用于缓存信息,即具有Key - Value的特性;另一个是可以对存储的数据设置过期时间;

    在这里笔者采用的是google开发工具类中的CacheBuilder构建本地缓存组件的,感兴趣的小伙伴可以自行搜索相关资料;然而这种实现方式在集群多实例部署的情况下是有问题的,因为CacheBuilder只适用于单一架构体系,所以如果是多实例集群部署的情况,最好用Redis。8b22ab26ef493287a87a82da4f4b89c6.png

    (1)文中涉及到的代码已经放在gitee上了,访问链接如下所示,别忘了给个star哦:https://gitee.com/steadyjack/SpringBootTechnologyA。

    (2)期间如何有任何问题都可以私信debug。

    (3)麻烦继续关注“程序员实战基地”,您的关注和转发 就是 debug勤劳写技术文的动力!!!5a6248719eab539b6cda4d7ca48f5a7b.png

    展开全文
  • Java接口重复提交

    千次阅读 2021-02-02 18:02:46
    背景 业务系统中的防重复提交都是由前端控制,后端在某些地方做了相应的业务逻辑相关的判断,但当某些情况下,前后端的判断都会失效,所以这里引入后端的接口重复提交校验。 方案选择 ...

    背景

    业务系统中的防重复提交都是由前端控制,后端在某些地方做了相应的业务逻辑相关的判断,但当某些情况下,前后端的判断都会失效,所以这里引入后端的接口防重复提交校验。

    方案

    由于需要限制的是部分接口,因此使用AOP+注解+Redis的方式来实现。AOP+注解的方式更加灵活,在需要限制的接口上加上注解即可。Redis则可以使防重复提交在分布式系统中使用。由于业务的特殊性,需要实现:1.同一个用户不能重复访问同一个接口;2.不同的用户不能以相同的参数同时访问同一个接口

    实现

    1.定义注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface RepeatSubmitVerify {
        /**
         * 设置请求锁定时间,单位:秒
         *
         * @return
         */
        int lockTime() default 10;
    
        /**
         * 参数名称
         *
         * @return
         */
        String paramString();
    }
    

    2.定义切面

    @Aspect
    @Component
    @Slf4j
    public class RepeatSubmitAspect {
    
        @Autowired
        private RedisLock redisLock;
    
        @Pointcut("@annotation(repeatSubmitVerify)")
        public void pointCut(RepeatSubmitVerify repeatSubmitVerify) {
        }
    
        @Around("pointCut(repeatSubmitVerify)")
        public Object around(ProceedingJoinPoint pjp, RepeatSubmitVerify repeatSubmitVerify) throws Throwable {
            int lockSeconds = repeatSubmitVerify.lockTime();
    
            String param = "{}";
            if (StringUtils.isNotBlank(repeatSubmitVerify.paramString())) {
                param = getKey(repeatSubmitVerify.paramString(), pjp);
            }
    
            JSONObject paramJson = JSON.parseObject(param);
            String token = paramJson.getString("token");
    
            // 这里需要设置两个lockKey,分别实现两个目的
            String key_prefix = pjp.getSignature().getDeclaringType().getSimpleName() + "_";
            // 接口名称+请求参数,避免不同的用户以相同的参数访问同时访问同一个接口
            String key1 = key_prefix + DigestUtils.md5Hex(paramJson.toJSONString());
            // 接口名称+用户token,避免同一个用户重复访问同一个接口
            String key2 = key_prefix + DigestUtils.md5Hex(token);
            // 上锁与解锁应该由同一个线程来执行,而不能其他线程来执行解锁,否则可能会出现错误解锁
            String clientId = getClientId();
    
    		// 上锁
            Boolean isSuccess = redisLock.tryLock(key1, key2, clientId, lockSeconds);
            Assert.notNull(isSuccess, "系统访问校验异常");
            if (isSuccess) {
                log.info("tryLock success, key1 = [{}], key2 = [{}], clientId = [{}]", key1, key2, clientId);
                // 获取锁成功
                Object result;
    
                try {
                    // 执行进程
                    result = pjp.proceed();
                } finally {
                    // 解锁
                    Boolean releaseLock = redisLock.releaseLock(key1, key2, clientId);
                    log.info("releaseLock success, key1 = [{}], key2 = [{}], clientId = [{}], result = [{}]", key1, key2, clientId, releaseLock);
                }
    
                return result;
    
            } else {
                // 获取锁失败,认为是重复提交的请求
                
                // 解锁这一步可以省略,在最终方案确定之前,上两把锁是分两步进行的,
                // 这样就会在重复请求时,其中一把上锁成功,而另一把不成功,判定上锁是失败的,
                // 因此要将成功的一把锁进行解锁,需要执行以下步骤
                // 而最终方案是通过lua脚本执行,要么成功上锁,两把锁都成功,要么失败,两把锁都失败,所以这一步可以省略
                Boolean releaseLock = redisLock.releaseLock(key1, key2, clientId);
                log.info("releaseLock success, key1 = [{}], key2 = [{}], clientId = [{}], result = [{}]", key1, key2, clientId, releaseLock);
                
                return errorData("操作已受理,请勿重复操作!");
            }
    
        }
    	//获取请求参数
        private String getKey(String key, JoinPoint joinPoint) {
            Method method = ((MethodSignature) (joinPoint.getSignature())).getMethod();
            String[] paramenterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(method);
            ExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression(key);
            EvaluationContext context = new StandardEvaluationContext();
            Object[] args = joinPoint.getArgs();
            if (args.length <= 0) {
                return "";
            }
            for (int i = 0; i < args.length; i++) {
                context.setVariable(paramenterNames[i], args[i]);
            }
            return expression.getValue(context, String.class);
        }
    	//获取每一次访问的UUID
        private String getClientId() {
            return UUID.randomUUID().toString();
        }
    }
    
    @Service
    @Slf4j
    public class RedisLock {
    	//lua脚本中的返回值判断需要特别注意
        private static final String RELEASE_LOCK_SCRIPT = "local p1 local p2 if redis.call('get', KEYS[1]) == KEYS[3] then p1 = redis.call('del', KEYS[1]) else p1 = 1 end if redis.call('get', KEYS[2]) == KEYS[3] then p2 = redis.call('del', KEYS[2]) else p2 = 1 end return p1~=0 or p2~=0";
        private static final String TRY_LOCK_SCRIPT = "if redis.call('exists', KEYS[1]) == 1 or redis.call('exists', KEYS[2]) == 1 then return 0 else redis.call('setex', KEYS[1], KEYS[4], KEYS[3]) redis.call('setex', KEYS[2], KEYS[4], KEYS[3]) return 1 end";
      
        @Autowired
        private StringRedisTemplate redisTemplate;
    
        /**
         * 该加锁方法仅针对单实例 Redis 可实现分布式加锁
         * 对于 Redis 集群则无法使用
         * <p>
         * 支持重复,线程安全
         *
         * @param lockKey1 加锁键
         * @param lockKey2 加锁键
         * @param clientId 加锁客户端唯一标识(采用UUID)
         * @param seconds  锁过期时间
         * @return
         */
        public Boolean tryLock(String lockKey1, String lockKey2, String clientId, long seconds) {
            try {
                Boolean result = redisTemplate.execute(new DefaultRedisScript<>(TRY_LOCK_SCRIPT, Boolean.class), Arrays.asList(lockKey1, lockKey2, clientId, String.valueOf(seconds)));
                log.info("tryLock, lockKey1 = [{}], lockKey2 = [{}], result = [{}], lockVal1 = [{}], lockVal2 = [{}]", lockKey1, lockKey2, result, redisTemplate.opsForValue().get(lockKey1), redisTemplate.opsForValue().get(lockKey1));
                return result;
                // return redisTemplate.opsForValue().setIfAbsent(lockKey1, clientId, seconds, TimeUnit.SECONDS)
                //         && redisTemplate.opsForValue().setIfAbsent(lockKey2, clientId, seconds, TimeUnit.SECONDS);
            } catch (Exception e) {
                return false;
            }
        }
    
        /**
         * 与 tryLock 相对应,用作释放锁
         *
         * @param lockKey1
         * @param lockKey2
         * @param clientId
         * @return
         */
        public Boolean releaseLock(String lockKey1, String lockKey2, String clientId) {
            try {
                return redisTemplate.execute(new DefaultRedisScript<>(RELEASE_LOCK_SCRIPT, Boolean.class), Arrays.asList(lockKey1, lockKey2, clientId));
            } catch (Exception e) {
                log.error("{}", e);
                return false;
            }
        }
    

    3.在需要处理的接口上打注解

    参考资料

    Redis eval命令踩得那些坑:https://github.com/nethibernate/blog/issues/7
    Redis分布式锁的正确实现方式:https://www.cnblogs.com/linjiqin/p/8003838.html
    CentOS7 安装lua环境:https://blog.csdn.net/houjixin/article/details/46634847
    参考Github代码仓库:https://github.com/MissDistin/repeat-submit-intercept

    展开全文
  • 正如本文标题所言,今天我们来聊一聊在Java应用系统中如何防止接口重复提交;简单地讲,这其实就是“重复提交”的话题,本文将从以下几个部分展开介绍: 1.“重复提交”简介与造成的后果 2.“防止接口重复提交”...

        正如本文标题所言,今天我们来聊一聊在Java应用系统中如何防止接口重复提交;简单地讲,这其实就是“重复提交”的话题,本文将从以下几个部分展开介绍: 

        1.“重复提交”简介与造成的后果

        2.“防止接口重复提交”的实现思路

        3.“防止接口重复提交”的代码实战

        一、“重复提交”简介与造成的后果

        对于“重复提交”,想必各位小伙伴都知晓它的意思,简单的理解,它指的是前端用户在间隔很短的时间周期内对同一个请求URL发起请求,导致前端开发者在很短的时间周期内将同一份数据(请求体)提交到后端相同的接口 多次,最终数据库出现多条主键ID不一样而其他业务数据几乎一毛一样的记录;

        仔细研究上述整个过程,会发现如果发起的多次请求的时间间隔足够短,即时间趋向于无穷小 时,其过程可以归为“多线程并发导致并发安全”的问题范畴;而对于“并发安全”的话题,debug早在此前自己录制的课程以及之前的文章中介绍过多次了,在此不再赘述;

        上述在对“重复提交”的介绍中隐约也提及它所带来的的后果:

        (1)数据库DB出现多条一毛一样的数据记录;

        (2)如果重复发起的请求足够多、请求体容量足够大,很可能会给系统接口带来极大的压力,导致其出现“接口不稳定”、“DB负载过高”,严重点甚至可能会出现“系统宕机”的情况;

    展开全文
  • Java开发中怎么防止重复提交

    千次阅读 2021-06-15 13:20:34
    这能避免用户按F5导致的重复提交,而其也不会出现浏览器表单重复提交的警告,也能消除按浏览器前进和后退按导致的同样问题。 3)在session中存放一个特殊标志 在服务器端,生成一个唯一的标识符,将它存入session,...
  • java防止重复提交解决方案

    千次阅读 2020-07-03 09:31:05
    java开发防止重复提交问题问题描述解决思路代码解释 问题描述 1.在我们项目开发过程中会出现用户保存操作时候快速点击两次会出现一条数据在数据库保存多条数据。 2.遇见上述问题我们首先跟前端开发沟通,在前端开发...
  • Java中如何避免重复提交请求

    千次阅读 2021-03-06 02:23:33
    查看后台日志后发现一个同样的请求提交了多次,后果就是轻则导致产生多条...二、产生原因导致重复请求的原因很多,大体为以下几种:多次点击提交按钮反复刷新页面点击浏览器后退按钮,导致重复提交表单浏览器重复的H...
  • java如何防止重复提交

    万次阅读 2018-01-22 14:44:22
    重复提交 ...2、刷新等 避免方式:Session防止令牌,交到页面...1、对要防止重复提交的操作,页面放置服务器Session的Token值  2、提交到后台后做验证 @RequestMapping("/add") public void add(HttpServletReque
  • 举栗子:当网络延迟的情况下,用户多次点击,多条数据插入到数据库,或者造成数据的不一致性,如提交订单,扣钱等。 简述一下前端解决思考 :按钮只让用户点击一次,重定向至友好页面,避免多次点击,此文主要介绍...
  • spring boot项目接口防止重复提交

    千次阅读 2022-01-11 15:04:10
    接口重复提交:是由于网络等原因,造成一瞬间发送多个请求,造成insert,update操作,多次数据被修改。如果多个请求时间间隔足够的小,那么可以理解为并发问题;即并发情况下,只有一次操作成功。 实现原理: 自定义...
  • Java后端防止频繁请求、重复提交

    千次阅读 2022-04-10 15:29:21
    Java后端防止频繁请求、重复提交 在客户端网络慢或者服务器响应慢时,用户有时是会频繁刷新页面或重复提交表单的,这样是会给服务器造成不小的负担的,同时在添加数据时有可能造成不必要的麻烦。所以我们在后端也有...
  • 这篇文章主要介绍了Java后台防止客户端重复请求、提交表单实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下前言在Web / App项目中,有一些请求或操作会...
  • 利用Redis实现防止接口重复提交功能

    千次阅读 2021-12-14 20:36:42
    据用户反映,当时网络有点卡,所以多点了几次提交,最后发现出现了十几条一样的数据。 只能说现在的人都太心急了,连这几秒的时间都等不了,惯的。心里吐槽归吐槽,这问题还是要解决的,不然老板可不惯我。 其实...
  • 来源:cnblogs.com/cjsblog/p/14516909.html概述为了防止掉单,这里可以这样处理:为了防止订单重复提交,可以这样处理:附上微信支付最佳实践:概述如图是一个简化...
  • /*** 防止重复提交的注解*/@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD})public @interface AvoidRepeatSubmit {long lockTime() default 1000;}import com.mushi.anno.AvoidRepeatSubmit;...
  • 由于网速等原因造成页面卡顿,用户重复刷新提交页面,甚至会有黑客或恶意用户使用工具重复恶意提交表单来对网站进行攻击,所以说防止表单重复提交在 Web 应用中的重要性是极高的。今天就和大家分享一下如何利用...
  • java 拦截重复请求 防止重复提交 超简单实现 准备工具 1.redis 2.自定义拦截注解 思路 1.注解里定义当前用户对当前接口访问最大间隔时间。 2.用户访问时在拦截器通过redis设置一个key-value-time。key识别用户,...
  • 本文实现一种分布式服务防重复提交的方案 也就是一线一个锁,在方法请求前,要先获取锁 如果锁存在则返回异常 。 下面简单介绍一下如何使用Redis实现分布式锁 CacheLock.java 为自定义注解接口,CacheLock方法注解...
  • Java实现防重复提交

    千次阅读 2020-07-04 15:19:44
    重复提交的重要性? 在业务开发中,为什么我们要去想办法解决重复提交这一问题发生?网上的概念很多:导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机,那么为什么会造成这种现象?...
  • 用户在操作表单Post数据时往往会出现表单数据重复提交的问题,尤其在Web开发中此类问题比较常见。刷新页面,后退操作以前的页面,单机多次按钮都会导致数据重复提交。此类问题是因为浏览器重复提交HTTP请求导致。...
  • 有一些场景,例如申请提交之后几秒内需要防止用户重复提交,我们后端通过自定义注解实现这一功能 需要的pom依赖: 在编写项目之前,如果要用自定义注解实现这一功能,需要导入spring aop,redis依赖等 <!--...
  • 重复提交代码

    2013-07-09 11:56:37
    java开发时防止jsp刷新造成的重复提交 经测试完美
  • 1、前言近期在构建项目脚手架时,关于接口幂等性问题,考虑做成独立模块工具放进脚手架中进行通用。如何保证接口幂等性,换句话说就是如何防止接口...2、方案基于JAVA注解+AOP切面方式实现防止重复提交,一般需要...
  • /** * 防止重复提交拦截器 */ @Component public class RepeatSubmitInterceptor implements HandlerInterceptor { public final String REPEAT_PARAMS = "repeatParams"; public final String REPEAT_TIME = ...
  • Java防止相同数据重复提交方案

    千次阅读 2020-06-08 23:35:07
    Java防止相同数据重复提交方案场景解决办法 场景 在开发工作中由于接口处理数据过慢,导致还没保存到数据库时再次提交相同的数据,此时数据库内没有这条数据出现了重复提交的脏数据 解决办法 1.前端控制提交未返回结果...
  • 关于接口重复提交的解决方案

    千次阅读 2021-11-15 17:54:58
    原理解释:第一次访问接口时,将某个标志存入redis,设置过期时间,例如三秒内访问超过一次就算重复提交,下次再访问时先查询redis中是否有缓存,有则说明3秒没过,返回错误信息,如果没有就是超过三秒了,可以访问 ...
  • redisson防止重复提交

    2022-01-04 13:24:26
    import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping;... } }else { log.info("重复提交:"+accountUriLockKey); } log.info("提交之后---"); return result; } }
  • 项目开发过程中接口面对防止重复请求、前台操作的抖动、快速操作、网络通信或者后端响应慢等等
  • 处理重复提交的请求: 1、前端控制 2、接口幂等性 3、数据库锁

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 48,092
精华内容 19,236
关键字:

java接口防止重复提交

java 订阅