美文网首页
SpringBoot实现表单重复提交检测

SpringBoot实现表单重复提交检测

作者: code2roc | 来源:发表于2021-10-12 15:27 被阅读0次

前言

在实际开发过程中,web应用经常会出现网络延迟,接口处理时间略长,用户习惯等原因造成的客户连续多次点击提交按钮调用接口,导致数据库会出现重复数据或这接口业务逻辑bug等问题

方案

利用redis锁实同一个用户同一个请求2秒内重复提交返回错误路由

SubmitLock

标记需要拦截的方法

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SubmitLock {
    int expire() default 2;
}

RedisLockUtil

redis锁校验及写入

@Component
public class RedisLockUtil {
    @Autowired
    private RedisUtil redisUtil;

    private int lockDBIndex = 1;

    public boolean lock(String key,String clientID,int lockExpire){
       if(redisUtil.isValid(key,lockDBIndex)){
            return false;
       }else{
           redisUtil.redisTemplateSet(key,clientID,lockDBIndex);
           redisUtil.setExpire(key,lockExpire, TimeUnit.SECONDS,lockDBIndex);
           return true;
       }
    }
}

RepeatSubmitAspect

统一拦截切面

@Aspect
@Component
@Order(value = 100)
public class RepeatSubmitAspect {
    private static Logger logger = LoggerFactory.getLogger(RepeatSubmitAspect.class);
    @Autowired
    private RedisLockUtil redisLockUtil;

    /**
     * 切面点 指定注解
     */
    @Pointcut("@annotation(com.haopan.frame.common.annotation.SubmitLock) " +
            "|| @within(com.haopan.frame.common.annotation.SubmitLock)")
    public void repeatSubmitAspect() {

    }

    /**
     * 拦截方法指定为 repeatSubmitAspect
     */
    @Around("repeatSubmitAspect()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        SubmitLock submitLock = method.getAnnotation(SubmitLock.class);
        if (submitLock != null) {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
            String token = request.getHeader("token");
            if (!StringUtil.isEmpty(token)) {
                String path = request.getServletPath();
                String key = "submitLock|" + token + "|" + path;
                String clientId = CommonUtil.getNewGuid();
                if (redisLockUtil.lock(key, clientId, submitLock.expire())) {
                    // 获取锁成功
                    return point.proceed();
                } else {
                    System.out.println("tryLock fail, key = ["+key+"]");
                    return Result.errorResult().setMsg("重复请求,请稍后再试").setCode(-980);
                }
            } else {
                return point.proceed();
            }
        } else {
            return point.proceed();
        }
    }
}

相关文章

  • SpringBoot实现表单重复提交检测

    前言 在实际开发过程中,web应用经常会出现网络延迟,接口处理时间略长,用户习惯等原因造成的客户连续多次点击提交按...

  • 12、Struts2表单重复提交

    什么是表单重复提交表单的重复提交:若刷新表单页面, 再提交表单不算重复提交.在不刷新表单页面的前提下:多次点击提交...

  • Struts2学习笔记 | 防止表单重复提交及自定义拦截器

    表单重复提交的概述 若刷新表单页面,再提交表单不算重复提交。 若是重定向,已经提交成功后再刷新不算重复提交。 以下...

  • 防止表单重复提交(springboot,redis)

    通过在controller加上CheckSubmitForm注解 ,用户访问连接时,aop进行代理拦截 reque...

  • Javascript-表单脚本

    一、表单的基础知识 1、表单提交 普通提交 以编程方式调用submit()方法提交表单 解决表单重复提交的办法:1...

  • JAVAWeb(第三周)

    表单提交方式 *使用submit提交 .... *使用button提交表单 -代码 //实现提交方法 functi...

  • 前端开发注意事项

    表单提交注意事项 1、避免重复提交,提交按钮做loading

  • 表单

    表单基础 提交表单 Tips: 解决重复提交表单的问题的两个方法1)在第一次提交表单后就禁用提交按钮2)利用ons...

  • 防止表单重复提交

    嘿,大家好,今天我来介绍几种简单的防止表单重复提交的方法: 防止表单重复提交 方法一:前端方式 当点击提交或者保存...

  • 002_JavaWeb避免重复提交

    JavaWeb避免重复提交 现象 利用Session防止表单重复提交 问题: 测试代码 更多信息:www.itco...

网友评论

      本文标题:SpringBoot实现表单重复提交检测

      本文链接:https://www.haomeiwen.com/subject/lnjholtx.html