创建拦截器
@Slf4j<br>public class IpUrlLimitInterceptor implements HandlerInterceptor {<br><br> @Resource<br> RedisUtils redisUtils;<br><br> private static final String LOCK_IP_URL_KEY="lock_ip_";<br><br> private static final String IP_URL_REQ_TIME="ip_url_times_";<br> //访问次数限制<br> private static final long LIMIT_TIMES=5;<br><br> //限制时间 秒为单位<br> private static final int IP_LOCK_TIME=300;<br><br> @Override<br> public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {<br> log.info("request请求地址uri={},ip={}",request.getRequestURI(), IpUtils.getRequestIP(request));<br> if(ipIsLock(IpUtils.getRequestIP(request))){<br> log.info("ip访问被禁止={}",IpUtils.getRequestIP(request));<br> throw new Exception("当前操作过于频繁,请5分钟后重试");<br> }<br> if (!addRequestTime(IpUtils.getRequestIP(request),request.getRequestURI())){<br> log.info("当前{}操作过于频繁,请5分钟后重试",IpUtils.getRequestIP(request));<br> throw new Exception("当前操作过于频繁,请5分钟后重试");<br> }<br> return true;<br> }<br><br> private boolean addRequestTime(String ip, String uri) {<br> String key = IP_URL_REQ_TIME+ip+uri;<br> if(redisUtils.hasKey(key)){<br> long time=redisUtils.incr(key,(long)1);<br> if(time >=LIMIT_TIMES){<br> redisUtils.set(LOCK_IP_URL_KEY+ip,IP_LOCK_TIME);<br> return false;<br> }<br> }else {<br> boolean set = redisUtils.set(key, (long) 1, 1);<br> }<br> return true;<br> }<br><br> private boolean ipIsLock(String ip) {<br> if(redisUtils.hasKey(LOCK_IP_URL_KEY+ip)){<br> return true;<br> }<br> return false;<br> }<br><br> @Override<br> public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {<br> HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);<br> }<br><br> @Override<br> public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {<br> HandlerInterceptor.super.afterCompletion(request, response, handler, ex);<br> }<br>}<br>
定义获取ip的工具
@Slf4j<br>public class IpUtils {<br> public static String getRequestIP(HttpServletRequest request){<br> String ip = request.getHeader("x-forwarded-for");<br> if(ip != null && ip.length() !=0 && "unknown".equalsIgnoreCase(ip)){<br> // 多次反向代理后会有多个ip值,第一个ip才是真实ip<br> if( ip.indexOf(",")!=-1 ){<br> ip = ip.split(",")[0];<br> }<br> }<br> if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){<br> ip = request.getHeader("Proxy-Client-IP");<br> log.info("Proxy-Client-IP ip: " + ip);<br> }<br> if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {<br> ip = request.getHeader("HTTP_CLIENT_IP");<br> log.info("HTTP_CLIENT_IP ip: " + ip);<br> }<br> if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {<br> ip = request.getHeader("HTTP_X_FORWARDED_FOR");<br> log.info("HTTP_X_FORWARDED_FOR ip: " + ip);<br> }<br> if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {<br> ip = request.getHeader("X-Real-IP");<br> log.info("X-Real-IP ip: " + ip);<br> }<br> if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {<br> ip = request.getRemoteAddr();<br> log.info("getRemoteAddr ip: " + ip);<br> }<br> return ip;<br> }<br>}
springboot中配置这个拦截器
@Configuration<br>public class WebConfig implements WebMvcConfigurer {<br> @Bean<br> IpUrlLimitInterceptor getIpUrlLimitInterceptor(){<br> return new IpUrlLimitInterceptor();<br> };<br> @Override<br> public void addInterceptors(InterceptorRegistry registry) {<br> registry.addInterceptor(getIpUrlLimitInterceptor()).addPathPatterns("/**");<br> }<br>}<br>