同一ip同一接口 一段时间内不可请求太多次
public class LoginFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(LoginFilter.class);
private static Set<String> effectiveURLs;
LoadingCache<String, AtomicLong> cache = null;
long maxRequest;
long cacheSecond;
public LoginFilter() {
}
public LoginFilter(long maxRequest,long cacheSecond) {
this.maxRequest = maxRequest;
this.cacheSecond = cacheSecond;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
effectiveURLs = new HashSet<>();
cache = CacheBuilder.newBuilder()
.maximumSize(10000)
.concurrencyLevel(100)
.recordStats()
.expireAfterWrite(cacheSecond, TimeUnit.SECONDS)
.build(new CacheLoader<String, AtomicLong>() {
@Override
public AtomicLong load(String s) throws Exception {
return new AtomicLong(1);
}
});
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestPath = httpRequest.getServletPath();
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,HEAD,OPTIONS,PUT");
httpResponse.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Access-token,Tourist-uuid,Channel-code");
String ip = CommonUtils.getIpAddr(httpRequest);
LOGGER.info("IP为 " + ip + " 此次访问路径 : " + requestPath);
try {
AtomicLong atomicLong = cache.getIfPresent(ip + "_" + requestPath);
if (atomicLong == null) {
atomicLong = new AtomicLong(1);
}
if (atomicLong.longValue() > maxRequest) {
LOGGER.error("异常请求 已达到最大请求次数 {}秒/{}次: ip:{},addr:{}",cacheSecond,maxRequest, ip, requestPath);
sendLimtErrorCodeMessage(httpResponse);
return;
}
atomicLong.incrementAndGet();
cache.put(ip + "_" + requestPath, atomicLong);
} catch (Exception e) {
LOGGER.error("过滤异常请求异常:", e);
}
chain.doFilter(request, response);
}
private void sendLimtErrorCodeMessage(HttpServletResponse response) {
try {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
BaseResult baseResult = new BaseResult(OperationStatus.REQUEST_ERROR);
String str = FastJsonUtil.toJSONStr(baseResult);
byte[] bytes = str.getBytes();
response.setContentLength(bytes.length);
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(bytes);
outputStream.flush();
} catch (Exception e) {
}
}
@Override
public void destroy() {
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*/
@Configuration
public class LoginFilterConfig {
@Value("${exception.request.maxRequest}")
private Long maxRequest;
@Value("${exception.request.cacheSecond}")
private Long cacheSecond;
@Bean
public FilterRegistrationBean openApiAuthenticationFilter() {
FilterRegistrationBean openApiFilter = new FilterRegistrationBean();
openApiFilter.setFilter(new LoginFilter(maxRequest,cacheSecond));
openApiFilter.addUrlPatterns("/*");
return openApiFilter;
}
}