1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
| /** * @author zxz * @date 2021/8/24 9:41 **/ @Component public class FangshuaInterceptor extends HandlerInterceptorAdapter { @Autowired private RedisUtil redisUtil; public ConcurrentHashMap<String,Integer> timeMap=new ConcurrentHashMap(); public ConcurrentHashMap<String,Integer> countMap=new ConcurrentHashMap();
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断请求是否属于方法的请求 if(handler instanceof HandlerMethod){ removeKey(); HandlerMethod hm = (HandlerMethod) handler; //获取方法中的注解,看是否有该注解 AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class); if(accessLimit == null){ return true; } //白名单 String whiteList=redisUtil.get("whitelist"); if(StringUtils.isNotBlank(whiteList)){ String ip=getIpAddr(request); String[] ips=whiteList.split(","); for (int i = 0; i <ips.length ; i++) { if(ip.equals(ips[i])){ return true; } } } //黑名单 String blacklist=redisUtil.get("blacklist"); if(StringUtils.isNotBlank(blacklist)){ String ip=getIpAddr(request); String[] ips=blacklist.split(","); for (int i = 0; i <ips.length ; i++) { if(ip.equals(ips[i])){ return false; } } }
int seconds = accessLimit.seconds(); int maxCount = accessLimit.maxCount(); boolean login = accessLimit.needLogin(); String key = request.getRequestURI(); //如果需要登录 if(login){ //获取登录的session进行判断 String sessionId=request.getSession().getId(); key=key+sessionId; } Integer second=timeMap.get(key); Integer count=countMap.get(key); if(count == null){ //第一次访问 threadMethodTime(key,seconds); countMap.put(key,1); }else if(count <= maxCount&&second>0){ countMap.put(key,count+1); }else if(count > maxCount&&second>0){ //拉入黑名单 String blacklistStr=redisUtil.get("blacklist"); blacklistStr= StringUtils.isEmpty(blacklistStr)?getIpAddr(request):blacklistStr+","+getIpAddr(request); redisUtil.set("blacklist",blacklistStr); //超出访问次数 render(response, ResultEnums.error1001); //这里的CodeMsg是一个返回参数 countMap.remove(key); return false; }else{ //超出访问次数 render(response, ResultEnums.error1001); //这里的CodeMsg是一个返回参数 countMap.remove(key); return false; } } return true;
} private void render(HttpServletResponse response, ResultEnums cm)throws Exception { response.setContentType("application/json;charset=UTF-8"); OutputStream out = response.getOutputStream(); String str = JSONUtil.toJsonStr(BaseRes.failure(cm.code,cm.value)); out.write(str.getBytes("UTF-8")); out.flush(); out.close(); } //删除时间到期的key private void removeKey(){ for (String secondKey:timeMap.keySet()) { Integer second=timeMap.get(secondKey); if(second!=null&&second==0){ countMap.remove(secondKey); timeMap.remove(secondKey); } } } /** * 获取真实IP * @param request * @return */ public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if ("0:0:0:0:0:0:0:1".equals(ip)) { ip = "127.0.0.1"; } if (ip.split(",").length > 1) { ip = ip.split(",")[0]; } return ip; }
//新增线程计算时间 public void threadMethodTime(String key,Integer seconds) { new Thread(() -> { // 线程本地变量,线程安全 ThreadLocal<Integer> local = new ThreadLocal<>(); local.set(seconds); for (int i = 0; i < seconds; i++) { if (local.get() != 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } local.set(local.get() - 1); timeMap.put(key,local.get()); } }
}).start(); } }
/** * @author zxz * @date 2021/8/24 10:27 **/ @Configuration public class WebConfig extends WebMvcConfigurationSupport { @Autowired private FangshuaInterceptor interceptor;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(interceptor).addPathPatterns("/**"); } }
|