package com.kmall.admin.aop; import com.kmall.admin.annotation.NoRepeatSubmit; import com.kmall.common.utils.RRException; import com.kmall.manager.manager.redis.JedisUtil; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Calendar; import java.util.Objects; /** * @author hj * @createDate 2021-04-29 */ @Aspect @Component @SuppressWarnings("all") public class RepeatSubmitAspect { private final static Logger logger = LoggerFactory.getLogger(RepeatSubmitAspect.class); public static final String KEYPREX = "noRpeat:user:"; /** * 进行接口防重复操作处理 * * @param pjp * @param noRepeatSubmit * @return */ @Around("execution(* com.kmall.admin.controller.*.*(..)) && @annotation(noRepeatSubmit) ") public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable { try { //获取request HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); //拿到token和请求路径 StringBuilder sb = new StringBuilder(); // sb.append(KEYPREX).append(request.getHeader("token").toString()).append(request.getRequestURI().toString()); sb.append(KEYPREX).append(request.getRequestURI().toString()); //获取现在时间 // long now = System.currentTimeMillis(); long now = Calendar.getInstance().getTimeInMillis(); if (JedisUtil.exists(sb.toString())) { //上次请求时间 // long lastTime = Long.valueOf(redisTemplate.opsForValue().get(sb.toString()).toString()); long lastTime = Long.valueOf(JedisUtil.get(sb.toString()).toString()); // 如果现在距离上次提交时间小于设置的默认时间 则 判断为重复提交 否则 正常提交 -> 进入业务处理 if ((now - lastTime) > noRepeatSubmit.lockTime()) { //重新记录时间 10分钟过期时间 // redisTemplate.opsForValue().set(sb.toString(), String.valueOf(now), 10, TimeUnit.MINUTES); JedisUtil.set(sb.toString(), String.valueOf(now), 10); //处理业务 Object result = pjp.proceed(); return result; } else { throw new RRException("点击的太快了,请慢一点!"); } } else { //第一次操作 JedisUtil.set(sb.toString(), String.valueOf(now), 10); // redisTemplate.opsForValue().set(sb.toString(),String.valueOf(now),10, TimeUnit.MINUTES); Object result = pjp.proceed(); return result; } } catch (Throwable e) { logger.error("校验表单重复提交时异常: {}", e.getMessage()); throw new RRException("校验重复提交时异常"); } } }