暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

spring boot 限制接口访问次数

猫公子xiu 2019-06-17
474

限制接口访问次数原因:防止恶意攻击和流量限制

首先自定义一个元注解

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
* @author 作者 : 小布
* @version 创建时间 : 2019年6月11日 下午3:54:07
* @explain 类说明 : 限制访问次数
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LimitKey {

//方法名称
String methodName() default "";

//访问次数
int frequency() default 10;

//业务KEY
String paramKey() default "CDPathSta";

//请求地址
String url() default "";

//过期时间
long timeout() default 1000;

}

然后对元注解 进行 操作

import java.util.HashMap;
import java.util.Map;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;


/**
* @author 作者 : 小布
* @version 创建时间 : 2019年6月11日 下午3:57:27
* @explain 类说明 : 限制访问次数
*/
@Component
@Order
@Aspect
public class LimitAspect {


private Map limitMap = new HashMap();


private static final Logger log = LoggerFactory.getLogger(LimitAspect.class);


@Pointcut("@annotation(limitKey)")
public void limit(LimitKey limitKey) {
}


@Around("limit(limitKey)")
public Object aroundLog(ProceedingJoinPoint joinpoint,LimitKey limitKey) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinpoint.getSignature();
int frequency = limitKey.frequency();
String methodName = limitKey.methodName();
String paramKey = limitKey.paramKey();
String url = limitKey.url();
//入参
String[] parameterNames = methodSignature.getParameterNames();
Object[] args = joinpoint.getArgs();
Object obj = null ;

for(int i = 0 ; i < parameterNames.length;i++) {
if(parameterNames[i].equals(paramKey)) {
obj = args[i];
break;
}
}

StringBuffer sb = new StringBuffer();
sb.append(url).append("/_").append(methodName).append("_").append(paramKey).append("_").append(obj).append("_key");
if(limitMap.get(sb.toString()) == null ) {
limitMap.put(sb.toString(),frequency-1);
} else {
int l = (int) limitMap.get(sb.toString());
if(l > 0){
limitMap.put(sb.toString(), --l);
} else {
Map<String, Object> mp = new HashMap<String, Object>();
mp.put("msg", 50003);//接口超过请求次数
return mp;
}
}
System.err.println("剩余次数:"+limitMap.get(sb.toString())+" 自定义key:"+sb.toString());
return joinpoint.proceed();
}


}

在controller 需要 限制次数的地方加上 刚刚自定义的元注解
@LimitKey(methodName=“名称”, url=“你的地址”) 这里的参数跟刚刚定义有关



文章转载自猫公子xiu,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论