1.编写切面代码
@Slf4j
@Aspect
@Component
public class RateLimitAspect {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Around("@annotation(rateLimit)")
public Object rateLimitAdvice(ProceedingJoinPoint joinPoint, RateLimit rateLimit) {
String methodName = joinPoint.getSignature().toShortString();
String key = "rate_limit:" + methodName;
// 从Redis中获取接口调用次数
String countStr = redisTemplate.opsForValue().get(key);
int count = (countStr != null) ? Integer.parseInt(countStr) : 0;
// 判断是否超过限流阈值
if (count >= rateLimit.limit()) {
throw new RuntimeException("接口调用次数超过限制");
}
// 调用接口方法,并将接口调用次数加一
Object result = null;
try {
result = joinPoint.proceed();
redisTemplate.opsForValue().increment(key);
} catch (Throwable throwable) {
log.info("接口掉用次数增加失败:{}",throwable);
}
return result;
}
}
2.自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
int limit();
}
3.应用
@Slf4j
@Controller
@RequestMapping("client/openInterface/pdd")
@ResponseBody
public class PddInterfaceController {
@Resource
PddShippingInfoFeign pddShippingInfoFeign;
@RateLimit(limit = 40000) // 设置每日最大调用次数为40000
@RequestMapping("/getShippingInfo")
public PddShippingInfoResp getShippingInfo(HttpServletRequest request) {
PddShippingInfoReq req = analizeRequest(request);
return pddShippingInfoFeign.getShippingInfo(req);
}
private PddShippingInfoReq analizeRequest(HttpServletRequest request) {
PddShippingInfoReq pddShippingInfoReq = new PddShippingInfoReq();
try {
pddShippingInfoReq.setPartnerId(request.getParameter("partnerId"));
pddShippingInfoReq.setDataDigest(request.getParameter("dataDigest"));
JSONObject parseObject = JSON.parseObject(request.getParameter("data"));
log.info("beforeData:{}", parseObject);
PddShippingData pdd = parseObject.toJavaObject(PddShippingData.class);
pddShippingInfoReq.setData(pdd);
log.info("lastDate:{}", pddShippingInfoReq.getData());
} catch (Exception e) {
log.error("PddInterfaceController.PddShippingInfoReq req:{}", request, e);
}
return pddShippingInfoReq;
}
}
4.前置通知
@Component
@Aspect
@Slf4j
public class UserInfoAspect {
@Pointcut("execution(* com.yunda.controller..*.*(..)) && !execution(* com.yunda.controller.app..*.*(..))")
public void setUserInfo() {
}
@Resource
private IdassUserPermissionService idaasUserPermissionServiceImpl;
private Pattern pattern = Pattern.compile("^9\\d*$");
@Before("setUserInfo()")
public void doBefore(JoinPoint joinPoint) throws Exception {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String uri = request.getRequestURI();
// 排除一些特殊的url
if (null != uri && uri.contains("app/dzg")) {
return;
}
boolean needSetBaseInfoFlag = false;
Object[] args = joinPoint.getArgs();
if (ObjectUtils.isNotEmpty(args)) {
for (Object arg : args) {
// log.info("arg:{}", arg.getClass().getName());
if (arg instanceof List) {
List list = (List) arg;
for (Object obj : list) {
if (obj instanceof LoginUserInfo) {
needSetBaseInfoFlag = true;
break;
}
}
}
if (arg instanceof LoginUserInfo &&
(((LoginUserInfo) arg).getLoginSiteId() == null
|| ((LoginUserInfo) arg).getLoginUserId() == null )) {
needSetBaseInfoFlag = true;
break;
}
}
if (!needSetBaseInfoFlag) {
log.info("need not user info");
return;
}
log.info("need user info");
CasUserInfo userInfo = CasUserUtils.getUserInfo();
if (userInfo != null) {
String orgCode = userInfo.getOrgCode() + "";
Long orgId;
//判断如果有9就不添加
orgId = Long.valueOf(String.format("9%s", orgCode));
//获取权限
RoleAndPermission roleAndPermission = (RoleAndPermission) idaasUserPermissionServiceImpl.getPermission(userInfo);
for (Object arg : args) {
if (arg instanceof List) {
List list = (List) arg;
for (Object obj : list) {
if (obj instanceof LoginUserInfo) {
((LoginUserInfo) obj).setLoginUserId(Long.valueOf(userInfo.getUserId()));
((LoginUserInfo) obj).setLoginUserName(userInfo.getUserName());
((LoginUserInfo) obj).setLoginSiteId(orgId);
((LoginUserInfo) obj).setLoginSiteName(userInfo.getOrgName());
((LoginUserInfo) obj).setPermission(roleAndPermission.getPermission());
((LoginUserInfo) obj).setRoles(roleAndPermission.getRoles());
}
}
}
if (arg instanceof LoginUserInfo) {
log.info("打印请求头:{}", request.getHeader("partLoginSiteId") + "-" + request.getHeader("partLoginSiteName"));
//判断是否有传输特殊登录网点
String partLoginSiteId = request.getHeader("partLoginSiteId");
String partLoginSiteName = request.getHeader("partLoginSiteName");
// String partLoginSiteId = "963001828";
// String partLoginSiteName = "综合处理组";
((LoginUserInfo) arg).setLoginUserId(Long.valueOf(userInfo.getUserId()));
((LoginUserInfo) arg).setLoginUserName(userInfo.getUserName());
((LoginUserInfo) arg).setLoginSiteId(orgId);
((LoginUserInfo) arg).setLoginSiteName(userInfo.getOrgName());
((LoginUserInfo) arg).setPermission(roleAndPermission.getPermission());
((LoginUserInfo) arg).setRoles(roleAndPermission.getRoles());
if (StringUtils.isNotBlank(partLoginSiteId) && StringUtils.isNotBlank(partLoginSiteName)) {
((LoginUserInfo) arg).setLoginSiteId(Long.valueOf(partLoginSiteId));
((LoginUserInfo) arg).setLoginSiteName(partLoginSiteName);
}
}
}
}
}
}
}