1.NoRepeatSubmit类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
/**
* 设置请求锁定时间
* 默认时间3,时间单位在下面
*/
int lockTime() default 3;
}
RepeatSubmitAspect类
@Aspect
@Component
public class RepeatSubmitAspect {
@Resource
private RedisUtil redisUtil;
@Pointcut("@annotation(noRepeatSubmit)")
public void pointCut(NoRepeatSubmit noRepeatSubmit) {
}
@Around("pointCut(noRepeatSubmit)")
public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
int lockSeconds = noRepeatSubmit.lockTime();
HttpServletRequest request = RequestUtils.getRequest();
Assert.notNull(request, "request can not null");
// 此处可以用token(请求的用户)
String token = request.getHeader("Authorization");
//请求的地址
String path = request.getServletPath();
//通过用户和请求地址标记唯一的key用来防止重复提交
String key = getKey(token, path);
//通过redis工具类方法判断redis里是否存在
//若存在则说明短时间(过期时间)内该用户访问过该地址,否则则没有(这里存的key加上了我这个项目的访问路径,其实不加也没事)
boolean isSuccess = redisUtil.exists(RedisKeyConstant.BASE_DIR + key);
if (isSuccess)
//如果访问过该地址,抛出异常
//三个参数分别为 http:状态码、自己代码封装的code码、报错信息
throw new BusinessException(CustomHttpStatus.BAD_REQUEST.value(), BusiCodeEnum
.PARAM_CUSTOM_ERROR.getCode(), "操作频繁,请稍后再试!");
//if语句只有一句话的话不拥有括号,到这里if判断就结束了
//没有访问过则在redis存入key,上面如果加了,这里也要加上,确定key是相同的
//过期时间 之前设置的*秒,这里的value是随意取的,因为与他也没关系
redisUtil.set(RedisKeyConstant.BASE_DIR + key, 1,
CommonConstant.SECONDS * lockSeconds, TimeUnit.SECONDS);
return pjp.proceed();
}
private String getKey(String token, String path) {
return token + path;
}
}