import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 防止惡意刷新接口, 控制在5秒內不能被刷新10次以上 * @author alex.liul * @create 2017.11.08 * @version 1.0 */ public class RequestLimitCache { private static final ConcurrentHashMap<String, CopyOnWriteArrayList<Long>> map = new ConcurrentHashMap<String, CopyOnWriteArrayList<Long>>(); private static final long EXPIRE_TIME = 1000 * 5L; private static final int MAX_REFRESH_COUNT = 10; private static final RequestLimitCache cache = new RequestLimitCache(); private RequestLimitCache() { Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(new ClearCacheRunnable(), 1000L, 500L, TimeUnit.MILLISECONDS); } public static RequestLimitCache getInstance() { return cache; } // 增長指定key的訪問次數 public void increment(String key) { CopyOnWriteArrayList<Long> list = map.get(key); if (list == null) { map.put(key, new CopyOnWriteArrayList<Long>()); } map.get(key).add(System.currentTimeMillis()); } // 是否到達指定數量 public boolean isUpCount(String key) { CopyOnWriteArrayList<Long> list = map.get(key); if (list == null) { return false; } return list.size() > MAX_REFRESH_COUNT; } // 清理過時數據線程 private static class ClearCacheRunnable implements Runnable { @Override public void run() { try { clear(); } catch (Exception e) { e.printStackTrace(); } } private void clear() { for (String key : map.keySet()) { CopyOnWriteArrayList<Long> list = map.get(key); for (Long date : list) { if ((System.currentTimeMillis() - date) > RequestLimitCache.EXPIRE_TIME) { list.remove(date); } } } } } }
import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 防止惡意刷新網站 控制網站的全部網頁在5秒內不能被刷新10次以上 * * @author alex.liul * @create 2013.3.21 * @version 1.0 */ public class RefreshFilter implements Filter { public void init(FilterConfig config) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String ip = req.getRemoteAddr(); //獲得客戶端IP地址 String requestURI = req.getRequestURI();//獲得客戶請求的uri String cache_key=ip+requestURI; Cache cache = Cache.getInstance(); if (cache.isUpCount(cache_key)) { res.setContentType("text/html; charset=UTF-8");// 響應類型 res.sendRedirect(req.getContextPath() + "/error.html"); } else { cache.increment(cache_key); chain.doFilter(request, response); } } public void destroy() { } // 緩存 private static class Cache { private static final ConcurrentHashMap<String, CopyOnWriteArrayList<Long>> map = new ConcurrentHashMap<String, CopyOnWriteArrayList<Long>>(); private static final long EXPIRE_TIME = 1000 * 5L; private static final long CLEAR_TIME = 500L; private static final int MAX_REFRESH_COUNT = 10; private static final Cache cache = new Cache(); private Cache() { new Thread(new ClearCacheRunnable()).start(); } public static Cache getInstance() { return cache; } // 增加指定url的點擊次數 public void increment(String key) { CopyOnWriteArrayList<Long> list = map.get(key); if (list == null) { map.put(key, new CopyOnWriteArrayList<Long>()); } map.get(key).add(new Long(System.currentTimeMillis())); } // 是否到達指定數量 public boolean isUpCount(String key) { CopyOnWriteArrayList<Long> list = map.get(key); if (list == null) { return false; } return list.size() > MAX_REFRESH_COUNT; } // 清理過時數據線程 private static class ClearCacheRunnable implements Runnable { @Override public void run() { while (true) { try { Thread.sleep(Cache.CLEAR_TIME); clear(); } catch (InterruptedException e) { e.printStackTrace(); } } } private void clear() { for (String key : map.keySet()) { CopyOnWriteArrayList<Long> list = map.get(key); for (Long date : list) { if ((System.currentTimeMillis() - date) > Cache.EXPIRE_TIME) { list.remove(date); } } } } } } }