直接上代码
1、 创建注解
/**
* @功能描述 防止重复提交标记注解
* @author gourd
* @date 2018-08-26
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
/**
* 重复统计时长
* @return
*/
int time() default 1;
}
2、AOP拦截切面
注意 将标识添加进了session ,还有可选方案进入redis缓存库或本地缓存。
/**
* 接口防重复切面
* @author gourd
* @date 2018-08-26
*/
@Aspect
@Component
@Slf4j
public class NoRepeatSubmitAop {
// 头变量
private static final String JWT_TOKEN_KEY = "Authorization";
//通过注解进入切面
@Pointcut("@annotation(io.dataease.commons.utils.repeat.NoRepeatSubmit)")
public void serviceNoRepeat() {
}
//前置
@Around("serviceNoRepeat()")
public Object around(ProceedingJoinPoint pjp) throws Exception {
//获取request
HttpServletRequest request = ServletUtils.request();
HttpSession session = request.getSession();
String jwtToken = request.getHeader(JWT_TOKEN_KEY);
String key = Md5Utils.md5(jwtToken + "-" + request.getRequestURL().toString()+"-"+ JSON.toJSONString(request.getParameterMap()));
if (session.getAttribute(key) == null) {
try {
Object o = pjp.proceed();
MethodSignature signature = (MethodSignature) pjp.getSignature();
NoRepeatSubmit noRepeatSubmit = signature.getMethod().getAnnotation(NoRepeatSubmit.class);
// 默认1秒内统一用户同一个地址同一个参数,视为重复提交
session.setAttribute(key,noRepeatSubmit);
removeAttrbute(session,key,noRepeatSubmit.time());
System.out.println(noRepeatSubmit.time());
return o;
}catch (Throwable e){
return ResultHolder.error(e.getMessage());
}
} else {
return ResultHolder.error("数据短时间内重复提交,请稍后再试");
}
}
/**
* 定时删除session中的key
* @param session session
* @param key 键
* @param s 秒
*/
private void removeAttrbute(final HttpSession session, final String key,int s) {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// 删除session中存的验证码
session.removeAttribute(key);
timer.cancel();
}
}, s * 1000L);
}
}
3 使用方法直接在方法前进行注解拦截