博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
黑名单设计
阅读量:5080 次
发布时间:2019-06-12

本文共 6377 字,大约阅读时间需要 21 分钟。

目标:实现黑名单机制,防止网络游戏爬虫

public class BlackListFilter implements Filter, ApplicationContextAware {    private final static Logger LOG = LoggerFactory.getLogger(BlackListFilter.class);    private WConfigService wConfigService;    private JedisClient jedisClient;    private static Map
queue = Maps.newConcurrentMap(); private final static String WISH_LIST_BLACK_LIST_CACHE = "wish_list_black_list_cache"; private final static int EXPIRE_TIME = 24 * 60 * 60; private final static String UN_KNOW = "unknown"; private final static String WCONFIG_NAME = "wConfigService"; private final static String JEDIS_NAME = "jedisClient"; private static ApplicationContext ctx; @Override public void init(FilterConfig filterConfig) throws ServletException { } private void init() { if (ctx != null && ctx.getBean(WCONFIG_NAME) != null && wConfigService == null) { wConfigService = (WConfigService) ctx.getBean(WCONFIG_NAME); } if (ctx != null && ctx.getBean(JEDIS_NAME) != null && jedisClient == null) { jedisClient = (JedisClient) ctx.getBean(JEDIS_NAME); } } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //防止NPE if (Objects.isNull(wConfigService) || Objects.isNull(jedisClient)) { init(); filterChain.doFilter(servletRequest, servletResponse); return; } //开关关闭 if (!wConfigService.obtainBlackListIsWork()) { filterChain.doFilter(servletRequest, servletResponse); return; } try { String ip = getIp(servletRequest); if (StringUtils.isBlank(ip)) { LOG.error("没有找到客户端ip"); filterChain.doFilter(servletRequest, servletResponse); return; } //判断是否在黑名单内 String blackListCache = Objects.nonNull(jedisClient.get(WISH_LIST_BLACK_LIST_CACHE)) ? jedisClient.get(WISH_LIST_BLACK_LIST_CACHE) : ""; List
blackList = CollectionUtils.isNotEmpty(JsonUtil.ofList(blackListCache, String.class)) ? JsonUtil.ofList(blackListCache, String.class) : Lists.newArrayList(); if (blackList.contains(ip)) { LOG.info("系统拒绝ip:" + ip + "的访问!"); throw new IllegalArgumentException(); } int count = 0; if (queue.keySet().contains(ip)) { count = queue.get(ip); count++; queue.put(ip, count); } else { count++; queue.put(ip, count); } int limitCount = Integer.valueOf(wConfigService.obtainBlackListLimitCount()); if (count >= limitCount) { synchronized (this) { queue.remove(ip); //超过访问次数限制,加入黑名单 if (CollectionUtils.isEmpty(blackList)) { //清除昨天的历史记录 queue = Maps.newConcurrentMap(); //第一次加入黑名单 blackList = Lists.newArrayList(); blackList.add(ip); jedisClient.set(WISH_LIST_BLACK_LIST_CACHE, JsonUtil.toJson(blackList)); jedisClient.expire(WISH_LIST_BLACK_LIST_CACHE, EXPIRE_TIME); } else { //黑名单增加ip blackList.add(ip); jedisClient.set(WISH_LIST_BLACK_LIST_CACHE, JsonUtil.toJson(blackList)); } filterChain.doFilter(servletRequest, servletResponse); } } else { filterChain.doFilter(servletRequest, servletResponse); } } catch (IllegalArgumentException e) { throw new IllegalArgumentException("今天的心愿太多了,请明天再来吧!"); } catch (Exception e) { LOG.error("黑名单过滤数据异常"); filterChain.doFilter(servletRequest, servletResponse); } } private String getIp(ServletRequest servletRequest) { String ip = ""; try { if (servletRequest instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest) servletRequest; String ipAddresses = request.getHeader("x-forwarded-for"); if (ipAddresses == null || ipAddresses.length() == 0 || UN_KNOW.equalsIgnoreCase(ipAddresses)) { //Proxy-Client-IP:apache 服务代理 ipAddresses = request.getHeader("Proxy-Client-IP"); } if (ipAddresses == null || ipAddresses.length() == 0 || UN_KNOW.equalsIgnoreCase(ipAddresses)) { //WL-Proxy-Client-IP:weblogic 服务代理 ipAddresses = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddresses == null || ipAddresses.length() == 0 || UN_KNOW.equalsIgnoreCase(ipAddresses)) { //HTTP_CLIENT_IP:有些代理服务器 ipAddresses = request.getHeader("HTTP_CLIENT_IP"); } if (ipAddresses == null || ipAddresses.length() == 0 || UN_KNOW.equalsIgnoreCase(ipAddresses)) { //X-Real-IP:nginx服务代理 ipAddresses = request.getHeader("X-Real-IP"); } //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP if (ipAddresses != null && ipAddresses.length() != 0) { ip = ipAddresses.split(",")[0]; } //还是不能获取到,最后再通过request.getRemoteAddr();获取 if (ip == null || ip.length() == 0 || UN_KNOW.equalsIgnoreCase(ipAddresses)) { ip = request.getRemoteAddr(); } } } catch (Exception e) { ip = ""; LOG.info("获取ip失败,失败原因:" + e.getMessage()); } return ip; } @Override public void destroy() { } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { BlackListFilter.ctx = applicationContext; }}

 

转载于:https://www.cnblogs.com/zhangchiblog/p/10907497.html

你可能感兴趣的文章
排球积分程序(三)——模型类的设计
查看>>
python numpy sum函数用法
查看>>
php变量什么情况下加大括号{}
查看>>
linux程序设计---序
查看>>
【字符串入门专题1】hdu3613 【一个悲伤的exkmp】
查看>>
C# Linq获取两个List或数组的差集交集
查看>>
HDU 4635 Strongly connected
查看>>
ASP.NET/C#获取文章中图片的地址
查看>>
Spring MVC 入门(二)
查看>>
格式化输出数字和时间
查看>>
页面中公用的全选按钮,单选按钮组件的编写
查看>>
java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程
查看>>
BZOJ 1047 HAOI2007 理想的正方形 单调队列
查看>>
各种语言推断是否是手机设备
查看>>
这个看起来有点简单!--------实验吧
查看>>
PHP count down
查看>>
JVM参数调优:Eclipse启动实践
查看>>
(旧笔记搬家)struts.xml中单独页面跳转的配置
查看>>
不定期周末福利:数据结构与算法学习书单
查看>>
strlen函数
查看>>