SPRING-AOP/Redis防止表单重复提交操作
1、新建防止表单重复提交注解:
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RequestLock {
String prefix() default "";
long expire();
TimeUnit timeUnit();
String delimiter() default "&";
}
2、AOP环绕通知监控注解 获取到登录姓名(un) + url地址
@Aspect
@Configuration
@Order(2)
public class RedisRequestLockAspect {
private final RedisTemplate stringRedisTemplate;
@Autowired
public RedisRequestLockAspect(RedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Pointcut("@within(io.hk.common.annotation.RequestLock) || @annotation(io.hk.common.annotation.RequestLock)")
public void aopPointCut() {
}
@Around("aopPointCut()")
public Object interceptor(ProceedingJoinPoint joinPoint) {
//获取自定义key
// 使用RedisCallback接口执行set命令,设置锁键;设置额外选项:过期时间和SET_IF_ABSENT选项
// stringRedisTemplate.opsForValue().set(lockKey, joinPoint.getArgs(), requestLock.expire(),requestLock.timeUnit());
try {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String methodName = methodSignature.getName();
if(methodName.equals("getUtilComboxList")||methodName.equals("getSubBusinessType")||methodName.equals("getUdiList")||methodName.equals("getMdparaconfig")||methodName.equals("getProject")){
return joinPoint.proceed();
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String un=request.getParameter("un")==null?"SYSTEM":request.getParameter("un").toString();
String uri=request.getRequestURI();
RequestLock requestLock = AnnotationUtils.findAnnotation(joinPoint.getTarget().getClass(), RequestLock.class);
// Object[] args = joinPoint.getArgs();
String lockKey =uri+"&"+un;
final Boolean success = (Boolean) stringRedisTemplate.execute(
(RedisCallback<Boolean>) connection -> connection.set(lockKey.getBytes(), new byte[0],
Expiration.from(requestLock.expire(), requestLock.timeUnit()),
RedisStringCommands.SetOption.SET_IF_ABSENT));
if (!success) {
LogUtil.writelog("存在key:" + lockKey, "防重复提交");
throw new RRException( "您的操作太快了,请稍后重试","1");
//return R.error("您的操作太快了,请稍后重试").put("message","您的操作太快了,请稍后重试");
}else {
Object retVal = this.execute(joinPoint, lockKey);
return retVal;
}
} catch (Throwable throwable) {
throw new RRException( throwable.getMessage(),"1");
//return R.error("系统异常,请联系管理员!").put("message","系统异常,请联系管理员!");
}
}
public Object execute(ProceedingJoinPoint pjp, String lockKey) throws Throwable {
Object var5;
try {
Object retVal = pjp.proceed();
var5 = retVal;
} catch (Exception var9) {
throw new Exception(var9);
} finally {
LogUtil.writelog("删除key:" + lockKey, "防重复提交");
stringRedisTemplate.delete(lockKey);
}
return var5;
}
}
三、将注解放到要防止重复提交的类上面
@RequestLock(expire=5,timeUnit= TimeUnit.MINUTES)
public class TestController {}
本文来自博客园,作者:skystrivegao,转载请注明原文链接:https://www.cnblogs.com/skystrive/p/18524959
整理不易,如果对您有所帮助 请点赞收藏,谢谢~