Redis锁防止重复提交

news/2024/11/29 19:39:27/

1.自定义注解方式

/*** @author :网寻星公众号* @date :Created in 2023/5/30 10:58* @description:Redis锁防止重复提交* @modified By:* @version: 1.0$*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RedisLock {int expire() default 5;
}

import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.RedisLock;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CheckSumBuilder;
import org.jeecg.common.util.IPUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;@Slf4j
@Aspect
@Configuration
public class RedisLockAspect {@Value("${spring.profiles.active}") # 本地还是正式 配置文件private String springProfilesActive;@Value("${spring.application.name}") #项目名称private String springApplicationName;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Pointcut("@annotation(org.jeecg.common.aspect.annotation.RedisLock)")public void point() {}@Around("point()")public Object doaround(ProceedingJoinPoint joinPoint) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();RedisLock localLock = method.getAnnotation(RedisLock.class);try {String lockUniqueKey = getLockUniqueKey(signature, joinPoint.getArgs());Integer expire = localLock.expire();if (expire < 0) {expire = 5;}ArrayList<String> keys = Lists.newArrayList(lockUniqueKey);String result = stringRedisTemplate.execute(setNxWithExpireTime, keys, expire.toString());if (!"ok".equalsIgnoreCase(result)) {//不存在log.info("重复提交,请稍后再试");
//                return BaseResult.error("不允许重复提交,请稍后再试");return Result.error("重复提交,请稍后再试");}return joinPoint.proceed();} catch (Throwable throwable) {throw new RuntimeException(throwable.getMessage());}}/*** lua脚本*/private RedisScript<String> setNxWithExpireTime = new DefaultRedisScript<>("return redis.call('set', KEYS[1], 1, 'ex', ARGV[1], 'nx');",String.class);/*** 获取唯一标识key** @param methodSignature* @param args* @return*/private String getLockUniqueKey(MethodSignature methodSignature, Object[] args) throws NoSuchAlgorithmException {//请求uri, 获取类名称,方法名称RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;HttpServletRequest request = servletRequestAttributes.getRequest();
//        HttpServletResponse responese = servletRequestAttributes.getResponse();//获取用户信息LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();String userMsg = sysUser.getUsername(); //获取登录用户名称//1.判断用户是否登录if (StringUtils.isEmpty(userMsg)) { //未登录用户获取真实ipuserMsg = IPUtils.getIpAddr(request);}String hash = "";List list = new ArrayList();if (args.length > 0) {String[] parameterNames = methodSignature.getParameterNames();for (int i = 0; i < parameterNames.length; i++) {Object obj = args[i];list.add(obj);}String param = JSONUtil.toJsonStr(list);hash = CheckSumBuilder.getMD5(param);}//项目名称 + 环境编码 + 获取类名称 + 加密参数String key = "lock:" + springApplicationName + ":" + springProfilesActive + ":" + userMsg + ":" + request.getRequestURI();if (StringUtils.isNotEmpty(key)) {key = key + ":" + hash;}return key;}}

使用

    @RedisLock@AutoLog(value = "添加数据")@ApiOperation(value="添加数据", notes="添加数据")@PostMapping(value = "/add")public Result<?> add(@RequestBody A a)throws Exception {testService.saveTo(a);return Result.OK("添加成功!");}

在这里插入图片描述


http://www.ppmy.cn/news/769632.html

相关文章

二十三种设计模式第十四篇--策略模式

策略模式&#xff1a;主要围绕一个类的行为或者其算法在运行时更改&#xff0c;也是一种行为型模式。 在软件开发中&#xff0c;我们经常遇到需要根据不同的情况选择不同算法或行为的情况。传统的做法是使用大量的条件语句来实现这种逻辑&#xff0c;但这样的实现方式往往难以…

如何变更Win10系统电脑的锁屏壁纸?分享经验!怎样选择Win10电脑的锁屏壁纸?

如今我们越来越多使用WIN10系统电脑来操作办公了&#xff0c;win10电脑系统对比于Win7系统许多选项简化了不少&#xff0c;win10系统的功能也是极为强大的&#xff0c;有许多是跟我们之前使用过的系统不同的&#xff0c;我们下面就开始对Win10系统如何变更锁屏壁纸操作进行讲解…

锁定计算机怎么换头像,电脑锁屏头像怎么设置

电脑锁屏头像怎么设置 当我们安装完Windows8系统之后&#xff0c;感觉个性化设置(锁屏、“开始”屏幕、用户头像)不满意&#xff0c;该如何更改个性化设置呢&#xff1f;下面就给大家介绍更改Windows8系统个性化设置的方法。请参考&#xff01; 电脑锁屏头像怎么设置 鼠标滑到电…

【HDFS学习】配额与存储策略

配额与存储策略 文章目录 配额与存储策略配额Name QuotasSpace QuotasStorage Type Quotas管理命令Reporting 命令 档案存储存储类型与存储策略存储类型: ARCHIVE, DISK, SSD and RAM_DISK存储策略: Hot, Warm, Cold, All_SSD, One_SSD, Lazy_Persist and Provided存储策略的生…

java项目之高校四六级报名管理系统(ssm+jsp+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的高校四六级报名管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌…

Visio安装

杂谈&#xff1a; 一般我们参加比赛、做实验&#xff0c;在写实验报告、说明书的时候&#xff0c;有时需要进行流程图&#xff0c;程序框图的绘制&#xff0c;使用word让人感觉心累&#xff0c;而Visio在这方面是非常专业的&#xff0c;也比较易上手。 资源&#xff1a;链接&am…

Visio2013激活/破解

出处&#xff1a;http://blog.csdn.net/keenweiwei/article/details/42780805/ 安装后&#xff0c;从 开始->程序-> KMSpico -> 启动 KMSpico 在这里点击大的红色按钮&#xff0c;稍等一会&#xff0c;即激活 visio 2013成功。 转载于:https://my.oschina.net/u/3732…

visio 2013 激活 办法

https://blog.csdn.net/TaoYuanKuangDao/article/details/78282999 从这下载&#xff01; 公司电脑装了杀毒软件&#xff0c;一直激活不了&#xff0c;他妈的好烦 花了一个小时时间 进入安全模式&#xff0c;然后装软件&#xff0c;ok