美文网首页
简单分布式锁解决表单重复提交

简单分布式锁解决表单重复提交

作者: 川流不息attitude | 来源:发表于2022-07-06 21:27 被阅读0次

前端按钮点击很快,有没有做置灰处理,反正后端不应该相信前端吧。

比如一下 添加接口 ,快速点击 可能会出现 两条重复数据,没有做唯一索引的话。

解决思路
  1. 定义一个小注解
  2. 定义一个切面
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotRepeatedSubmit {
    String msg() default "请勿重复提交";
}
@Aspect
@Component
public class NotRepeatedSubmitAspect {

    private static final String LOCK_REPEATED_SUBMIT = "lock_repeated_submit:";
    @Autowired
    private RedissonClient redissonClient;

    @Around("@annotation(notRepeatedSubmit)")
    public Object around(ProceedingJoinPoint pjp, NotRepeatedSubmit notRepeatedSubmit) throws Throwable {
        try {
            //获取当前执行类
            String className = pjp.getSignature().getDeclaringTypeName();
            //获取当前执行类中的执行方法
            String methodName = pjp.getSignature().getName();
            // 参数
            Map<String, Object> params = getRequestParams(pjp);
            String md5 = SecureUtil.md5(className + methodName + JSON.toJSONString(params));
            RLock lock = redissonClient.getLock(LOCK_REPEATED_SUBMIT+md5);
            boolean tryLock = lock.tryLock();
            if(tryLock){
                try {
                    Object result = pjp.proceed();
                    return result;
                } finally {
                    lock.unlock();
                }
            }
            throw new BusinessException(notRepeatedSubmit.msg());
        } catch (Throwable e) {
            throw e;
        }
    }


    /**
     * 获取入参
     * @param proceedingJoinPoint
     *
     * @return
     * */
    private Map<String, Object> getRequestParams(ProceedingJoinPoint proceedingJoinPoint) {
        Map<String, Object> requestParams = new HashMap<>();
        //参数名
        String[] paramNames =
                ((MethodSignature)proceedingJoinPoint.getSignature()).getParameterNames();
        //参数值
        Object[] paramValues = proceedingJoinPoint.getArgs();

        for (int i = 0; i < paramNames.length; i++) {
            Object value = paramValues[i];
            //如果是文件对象
            if (value instanceof MultipartFile) {
                MultipartFile file = (MultipartFile) value;
                //获取文件名
                value = file.getOriginalFilename();
            }

            if(value instanceof HttpServletResponse){
                continue;
            }
            if(value instanceof HttpServletRequest){
                continue;
            }
            requestParams.put(paramNames[i], value);
        }
             // 附加用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String principal = "";
        if(null != authentication){
            principal = authentication.getName();
        }
        requestParams.put("username",principal);
        return requestParams;
    }
}

使用 就在方法上打个注解

相关文章

  • 简单分布式锁解决表单重复提交

    前端按钮点击很快,有没有做置灰处理,反正后端不应该相信前端吧。比如一下 添加接口 ,快速点击 可能会出现 两条重复...

  • Javascript-表单脚本

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

  • 12、Struts2表单重复提交

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

  • 解决表单重复提交

    解决方案 使用javascript 解决 既然存在上述所说的表单重复提交问题,那么我们就要想办法解决,比较常用的方...

  • 解决表单重复提交

    最安全正确方式 解决表单重复提交在服务器端生成一个唯一标识 令牌 token同时在当前用户的session中保存这...

  • 表单

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

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

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

  • 防止表单重复提交

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

  • 使用预定义的token拦截器

    • token拦截器用于解决表单的重复提交。 • 使用步骤: 注意: 在form表单添加token拦截器时,需要将...

  • 分布式锁及分布式事务

    分布式锁是解决并发时资源争抢的问题,分布式事务和本地事务是解决流程化提交问题。一、其中分布式锁实现:1.基于数据库...

网友评论

      本文标题:简单分布式锁解决表单重复提交

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