|
@@ -1,11 +1,8 @@
|
|
|
package com.jiayue.ssi.aspectj;
|
|
|
|
|
|
-import java.util.concurrent.ConcurrentHashMap;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
-
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
-
|
|
|
import com.jiayue.ssi.annotation.InterfaceLimit;
|
|
|
+import com.jiayue.ssi.util.InterfaceLimitUtil;
|
|
|
import org.aspectj.lang.ProceedingJoinPoint;
|
|
|
import org.aspectj.lang.annotation.Around;
|
|
|
import org.aspectj.lang.annotation.Aspect;
|
|
@@ -14,12 +11,8 @@ import org.springframework.stereotype.Component;
|
|
|
import org.springframework.web.context.request.RequestAttributes;
|
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
-import com.jiayue.ssi.util.IPUtils;
|
|
|
import com.jiayue.ssi.util.ResponseVO;
|
|
|
-
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import net.jodah.expiringmap.ExpirationPolicy;
|
|
|
-import net.jodah.expiringmap.ExpiringMap;
|
|
|
|
|
|
/**
|
|
|
* 接口限制实现
|
|
@@ -31,8 +24,6 @@ import net.jodah.expiringmap.ExpiringMap;
|
|
|
@Component
|
|
|
@Slf4j
|
|
|
public class InterfaceLimitAspect {
|
|
|
- private static ConcurrentHashMap<String, ExpiringMap<String, Integer>> book = new ConcurrentHashMap<>();
|
|
|
-
|
|
|
/**
|
|
|
* 层切点
|
|
|
*/
|
|
@@ -46,25 +37,12 @@ public class InterfaceLimitAspect {
|
|
|
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
|
|
|
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
|
|
HttpServletRequest request = sra.getRequest();
|
|
|
-
|
|
|
- // 获取Map value对象, 如果没有则返回默认值
|
|
|
- // getOrDefault获取参数,获取不到则给默认值
|
|
|
- ExpiringMap<String, Integer> uc = book.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build());
|
|
|
- Integer uCount = uc.getOrDefault(IPUtils.getIpAddr(request), 0);
|
|
|
- if (uCount >= interfaceLimit.value()) { // 超过次数,不执行目标方法
|
|
|
+ if (!InterfaceLimitUtil.checkInterface(request,interfaceLimit.time(),interfaceLimit.value())){
|
|
|
log.error("接口拦截:{} 请求超过限制频率【{}次/{}ms】,IP为{}", request.getRequestURI(), interfaceLimit.value(), interfaceLimit.time(), request.getRemoteAddr());
|
|
|
return ResponseVO.fail(null,"请求过于频繁,请稍后再试");
|
|
|
- } else if (uCount == 0) { // 第一次请求时,设置有效时间
|
|
|
- uc.put(request.getRemoteAddr(), uCount + 1, ExpirationPolicy.CREATED, interfaceLimit.time(), TimeUnit.MILLISECONDS);
|
|
|
- } else { // 未超过次数, 记录加一
|
|
|
- uc.put(request.getRemoteAddr(), uCount + 1);
|
|
|
}
|
|
|
- book.put(request.getRequestURI(), uc);
|
|
|
-
|
|
|
// result的值就是被拦截方法的返回值
|
|
|
ResponseVO result = (ResponseVO)pjp.proceed();
|
|
|
-
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
}
|