通过注解方式,在aop中判断是否重复提交。
整个流程如下。
image.png
注解
/**
* @author river
* @date 2019/5/27 11:38
**/
@Retention(RUNTIME)
@Target(ElementType.METHOD)
public @interface NoRepeatSubmit {
}
AOP 内处理业务
/**
* @author river
* @date 2019/5/27 11:40
**/
@Aspect
@Component
@Slf4j
public class NoRepeatSubmitAop {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public static final String NO_REPEAT_COMMIT = "NO_REPEAT_COMMIT:";
@Around("@annotation(noRepeatSubmit)")
public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
HttpServletRequest request = attributes.getRequest();
String key = NO_REPEAT_COMMIT + sessionId + "-" + request.getServletPath();
// 如果缓存中有这个url视为重复提交
if (opsForValue.get(key) == null) {
Object o = pjp.proceed();
opsForValue.set(key, "no repeat commit", 2, TimeUnit.SECONDS);
return o;
}
log.debug("key = {} 重复提交", key);
// 抛出异常 - 给前端
throw new Exception("重复提交");
}
}
这样如果是2秒内 同一个 url 的请求,就会被拦截(抛出异常)。
网友评论