防重复请求注解测试

相同参数,一定时间内,重复请求拦截

主要代码如下:

RepeatRequest.java 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatRequest {
String value() default "";
}
RepeatRequestAspect.java

@Aspect
@Component
public class RepeatRequestAspect {

private static final Logger LOGGER = LoggerFactory.getLogger(RepeatRequestAspect.class);

/**
* 执行切面拦截逻辑
*/
@Around("@annotation(repeatRequest)")
public Object execute(ProceedingJoinPoint joinPoint, RepeatRequest repeatRequest) throws Throwable {
if (repeatRequest != null) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

StringBuffer sb=new StringBuffer("");
//1.获取参数
HttpServletRequest request=attributes.getRequest();
HttpServletResponse response=attributes.getResponse();

//ip
sb.append("ip:");
String ip = ToolUtil.getClientIp(request);
sb.append(ip);

//header
sb.append("head:");
Enumeration<String> headers=request.getHeaderNames();
while(headers.hasMoreElements()){
String heardName =headers.nextElement();
String heardValue= request.getHeader(heardName);
sb.append(heardName).append("=").append(heardValue).append(";");
}

//body
sb.append("body:");
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
Object o = args[i];
sb.append(o.toString());
}

//2.所有 请求头、报文体 进行组装,查询redis 是否存在记录

LOGGER.info("sb="+sb.toString());

//sha 加密 、base64
QETag tag = new QETag();
String hash = tag.calcETag(sb.toString());
LOGGER.info("hash="+hash);

//存redis
String key = "request_key_" + hash;
String value=CacheUtils.get(key);

if(!StringUtil.isEmpty(value)){
//3.存在记录
//response.setStatus(304);
//怕摘要重复 可进行value处理,碰撞几率太小,可以忽略...
return RestResponse.failure("请勿重复请求");
}else{
//4.不存在记录,将所有参数组装写入redis,失效时间为3秒
CacheUtils.put(key, sb.toString(), 3);
}



}
return joinPoint.proceed();
}


}

tag.calcETag 其实就是 sha1 加密,然后再base64 -_-

就这样啦
 
posted @ 2019-09-20 17:32  小猴子下山  阅读(406)  评论(0编辑  收藏  举报