概要
利用注解在那些需要需要重复校验的接口上
在aop切面中拦截参数,
把 签名sign = MD5(参数+requestURI+userId),存储在redis中,存储5秒钟,以后的每次请求都要判断redis中是否存在重复sign
具体实现
/**
* 防止重复提交标记注解
*
* @author sairobo
* @date 2019年11月26日 上午10:19:56
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeatSubmit {
/**
* 几秒之内无法重复提交请求(单位秒)
*
* @return
*/
int expire() default 5;
}
@Aspect
@Configuration
@Slf4j
public class NoRepeatSubmitAspect {
@Autowired
private RedisUtils redisUtils;
@NacosValue("${api.norepeat.submit.open:true}")
private boolean isOpen;
@Pointcut("@annotation(edu.xxx.web.modules.openapi.annotation.NoRepeatSubmit)")
public void noRepeatSubmit() {
}
@Around("noRepeatSubmit()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
if (!isOpen) {
return pjp.proceed();
}
Stopwatch watch = Stopwatch.createStarted();
Object proceed;
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
NoRepeatSubmit noRepeatSubmit = method.getAnnotation(NoRepeatSubmit.class);
// 执行验证
executeValidation(HttpKit.getRequest(), pjp, noRepeatSubmit.expire());
log.error(" 校验执行时长:{} {}!", watch.elapsed(TimeUnit.MILLISECONDS), "毫秒");
proceed = pjp.proceed();
return proceed;
}
/**
* 验证是否重复提交
* @param request
* @param pjp
* @param expire 超时,单位秒
* @throws IOException
*/
private void executeValidation(HttpServletRequest request, ProceedingJoinPoint pjp, int expire) throws IOException {
String requestURI = request.getRequestURI();
Object[] args = pjp.getArgs();
String paramJsonStr = "";
if (args != null) {
for (int i = 0; i < args.length; i++) {
paramJsonStr.concat(JSON.toJSONString(args[i]));
}
}
Long swUserId = Convert.toLong(request.getAttribute(USER_KEY));
// sign = md5(请求参数的json请求体字符串 + requestURI + swUserId)
String digest = DigestUtils.md5DigestAsHex((paramJsonStr.concat(requestURI).concat(Convert.toStr(swUserId, "")).getBytes()));
if (redisUtils.exists(digest)) {
throw new RRException("重复请求!", HttpStatus.INTERNAL_SERVER_ERROR.value());
}
redisUtils.set(digest, 1, expire);
}
}
网友评论