1、先自定义一个注解
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestDelay {
/**
* 用户id参数
* 不能为空
*/
String userId();
}
2、注解的使用
指定userId 为参数aa里面的userId字段
@PostMapping("/xx/xx")
@RequestDelay(userId = "xx.userId")
public Response inquiryQuickRefund(@RequestBody @Valid aa aa ){
```
3、aop实现
```java
@Component
@Aspect
@Slf4j
public class RequestDelayAspect {
String REQUEST_DELAY_KEY = "REQUEST_DELAY_KEY: ";
@Resource
RedisUtil redisUtil;
@Pointcut("@annotation(com.qschou.health.inquiry.common.aop.anno.RequestDelay)")
public void cut() {}
// 先引入上面@Pointcut注解的方法名,在加上@annotation,
// @annotation中的值,需要和action方法中的参数名称相同(必须相同,但是名称任意)这样可以拿到注解上的值
@Around("cut() && @annotation(delay)")
public Object delay(ProceedingJoinPoint pjp, RequestDelay delay) {
Object[] args = pjp.getArgs();
MethodSignature signature = (MethodSignature)pjp.getSignature();
String[] parameterNames = signature.getParameterNames();
String annoParams = delay.userId();//注解上的值
Object userId = getParamValue(args, parameterNames, annoParams);
if(userId == null){
return Response.error("注解中,指定参数中的userId不能为空或者注解上配置的参数不存在");
}
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request =
(HttpServletRequest)requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
String uri = request.getRequestURI();
log.info("获取token,token:{},uri:{}", userId, uri);
Object obj = null;
try {
obj = redisUtil.get(REQUEST_DELAY_KEY + uri + userId);
} catch (Exception e) {
log.error("redis 异常");
}
if (obj != null)
return Response.error("点击过于频繁");
try {
redisUtil.set(REQUEST_DELAY_KEY + uri + userId, userId, 3);
} catch (Exception e) {
log.error("redis 异常");
}
try {
return pjp.proceed();
} catch (Throwable throwable) {
return Response.error(SYSTEM_ERROR, SYSTEM_ERROR.getMessage());
}
}
private Object getParamValue(Object[] args, String[] parameterNames, String annoParams) {
String[] annoParamArr = annoParams.split("\\.");
String paramPrefix = annoParamArr[0];
String paramSuffix = annoParamArr[1];
int index = ArrayUtils.indexOf(parameterNames, paramPrefix);
if (index != -1) {
String json = JsonUtil.toJson(args[index]);
Object userId = null;
try {
userId = JsonPath.parse(json).read("$." + paramSuffix);
} catch (Exception e) {
return null;
}
return userId;
}
return null;
}
}