|
@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* desc:利用用户token及请求url 防止用户重复提交,需要在没有唯一索引的保存或修改操作 方法入口上加上@NoRepeatSubMit注解 |
|
|
* desc:利用用户token及请求url 防止用户重复提交,需要在没有唯一索引的保存或修改操作 方法入口上加上@NoRepeatSubMit注解 |
|
|
|
|
|
* |
|
|
* @author zhaoqifeng |
|
|
* @author zhaoqifeng |
|
|
* @dscription |
|
|
* @dscription |
|
|
* @date 2020/11/24 9:59 |
|
|
* @date 2020/11/24 9:59 |
|
@ -33,8 +34,8 @@ public class NoRepeatSubmitAop { |
|
|
@Autowired |
|
|
@Autowired |
|
|
private DistributedLock distributedLock; |
|
|
private DistributedLock distributedLock; |
|
|
|
|
|
|
|
|
@Around("@annotation(noRepeatSubmit)") |
|
|
@Around("@annotation(noRepeatSubmit)") |
|
|
public Object around(ProceedingJoinPoint pjp,NoRepeatSubmit noRepeatSubmit) { |
|
|
public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) { |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
|
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
|
@ -44,21 +45,23 @@ public class NoRepeatSubmitAop { |
|
|
String key = getKey(request.getRequestURI(), internalToken); |
|
|
String key = getKey(request.getRequestURI(), internalToken); |
|
|
// 如果缓存中有这个url视为重复提交
|
|
|
// 如果缓存中有这个url视为重复提交
|
|
|
Object result = null; |
|
|
Object result = null; |
|
|
|
|
|
RLock lock = null; |
|
|
try { |
|
|
try { |
|
|
long leaseTime = noRepeatSubmit.leaseTime(); |
|
|
long leaseTime = noRepeatSubmit.leaseTime(); |
|
|
//如果获取不到锁等待0秒直接返回 持锁时间为leaseTime
|
|
|
//如果获取不到锁等待0秒直接返回 持锁时间为leaseTime
|
|
|
RLock lock = distributedLock.getLock(RedisKeys.getNoRepeatSubmitKey(key), leaseTime, NumConstant.ZERO_L, TimeUnit.MILLISECONDS); |
|
|
lock = distributedLock.getLock(RedisKeys.getNoRepeatSubmitKey(key), leaseTime, NumConstant.ZERO_L, TimeUnit.MILLISECONDS); |
|
|
try { |
|
|
|
|
|
//因为getLock如果获取失败抛异常 所以不做锁状态的判断
|
|
|
|
|
|
result = pjp.proceed(); |
|
|
|
|
|
} finally { |
|
|
|
|
|
distributedLock.unLock(lock); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
log.warn("noRepeatSubmit exception",e); |
|
|
log.warn("noRepeatSubmit key:{},msg:{}", key, e.getMessage()); |
|
|
//"未获取到锁,重复提交了
|
|
|
//"未获取到锁,重复提交了
|
|
|
throw new RenException(EpmetErrorCode.REPEAT_SUBMIT.getCode()); |
|
|
throw new RenException(EpmetErrorCode.REPEAT_SUBMIT.getCode()); |
|
|
} |
|
|
} |
|
|
|
|
|
try { |
|
|
|
|
|
//因为getLock如果获取失败抛异常 所以不做锁状态的判断
|
|
|
|
|
|
result = pjp.proceed(); |
|
|
|
|
|
} finally { |
|
|
|
|
|
distributedLock.unLock(lock); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
|
} catch (RenException e) { |
|
|
} catch (RenException e) { |
|
@ -67,10 +70,10 @@ public class NoRepeatSubmitAop { |
|
|
log.error("验证重复提交时出现未知异常!"); |
|
|
log.error("验证重复提交时出现未知异常!"); |
|
|
throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); |
|
|
throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private String getKey(String keyExpress,String token) { |
|
|
private String getKey(String keyExpress, String token) { |
|
|
return keyExpress+token; |
|
|
return keyExpress + token; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|