实现思路源码
拦截器类webConfig
实现思路该拦截器通过获取访问者主机IP地址及访问接口,放入map集合中,实现同一接口、同一IP短时间内调用次数限制
源码 拦截器类该拦截器在调用接口之前执行
IpUtil是我自己写的一个工具类cntool中的获取IP方法,关于这个工具类看这儿
ExpiringMap是一个可以设置时效的Map集合,.expiration(3, TimeUnit.SECONDS)参数第一个是生效时间,这个生效时间是以秒来计的,比如说你想让存的键值生效时间为1分钟,那就在第一个参数的位置写上60,5分钟的话就写上300,以此类推
package com.zygh.nodemanage.component;
import com.cntool.core.ip.IpUtil;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@Component
public class RepeatHandler implements HandlerInterceptor {
private ExpiringMap timeMap = ExpiringMap.builder()
// 设置每个key有效时间3s, 如果key不设置过期时间,key永久有效
.expiration(3, TimeUnit.SECONDS)
// 允许更新过期时间值
.variableExpiration()
// CREATED: 只在put和replace方法重置过期时间
.expirationPolicy(ExpirationPolicy.CREATED).build();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
//获取用户访问地址
String requestUrl = request.getRequestURI();
System.out.println(requestUrl);
String ipAddr = IpUtil.getIpAddr(request);
if (requestUrl.equals(timeMap.get(ipAddr))) {
response.setHeader("Content-Type", "application/json;charset=utf-8");
response.getWriter().print("{"code":403,"message":"手速太快,注意鼠标身体呦~"}");
response.getWriter().flush();
return false;
}
timeMap.put(ipAddr, requestUrl);
System.out.println(timeMap.size());
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
webConfig
在addInterceptors方法中,addPathPatterns为设置拦截路径 @Configuration public class WebConfig extends WebMvcConfigurationSupport { @Override public void addInterceptors(InterceptorRegistry registry) { //注册Interceptor拦截器 registry.addInterceptor(repeatHandler) .addPathPatterns("get*") .excludePathPatterns("list*") .excludePathPatterns("*List") .excludePathPatterns("query*"); } }
到这里就大功告成了



