防止用户恶意刷新过滤器

2024-05-14 23:38

本文主要是介绍防止用户恶意刷新过滤器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

防止用户恶意刷新过滤器
2012-08-15       0 个评论      
收藏     我要投稿
为了防止用户对网站页面刷新过于频繁,需要对这种恶意操作进行判断并且屏蔽.虽然公司要有这样的一个功能,但是我觉得太没有必要了.只要你服务器够好,你何必需要这样的功能呢?下面是全部代码(仅供大家参考,我觉得实际意义不是很大):
 
import java.io.IOException; 
import java.util.Map; 
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; 
 
import com.f139.frame.util.NetUtil; 
 
public class RefreshFilter implements Filter { 
 
    private static final Map<String, Integer> ipcount = new ConcurrentHashMap<String, Integer>(); 
 
    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws IOException, ServletException { 
 
        try { 
            filter((HttpServletRequest) request, 
                    (HttpServletResponse) response, chain); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 
    } 
 
    private void filter(HttpServletRequest request, 
            HttpServletResponse response, FilterChain chain) 
            throws IOException, ServletException, InterruptedException { 
        response.setCharacterEncoding("UTF-8"); 
        request.setCharacterEncoding("UTF-8"); 
        // 获得用户的IP地址,根据用户IP地址来判断此用户是否刷新过于频繁 
        String userIP = NetUtil.getIpAddr(request); 
        Cache cache = Cache.getInstance(); 
        cache.increment(userIP); 
        if (cache.isUpCount(userIP)) { 
            Integer count = ipcount.get(userIP); 
            if (count != null) { 
                ipcount.put(userIP, count + 1); 
                System.out.println(ipcount.get(userIP)); 
            } else { 
                count = 0; 
                ipcount.put(userIP, count + 1); 
            } 
            if (ipcount.get(userIP) > 3) { 
                response.getWriter().println("很抱歉,您操作过于频繁."); 
                //403页面 
                ((HttpServletResponse) response) 
                        .sendError(HttpServletResponse.SC_FORBIDDEN); 
                /**
                 * 在这里可以使用quartz工作调度对map进行定时的清理,时被禁止的用户可以重新访问本页面
                 */ 
                return; 
            } 
            response.getWriter().println("操作频繁,请3秒后再试"); 
            return; 
        } 
        chain.doFilter(request, response); 
    } 
 
    @Override 
    public void destroy() { 
 
    } 
 
    @Override 
    public void init(FilterConfig config) throws ServletException {  
 
    } 
 
    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; 
        // 用户频繁刷新次数上限,第六次就禁止刷新 www.2cto.com
        private static final int MAX_COUNT = 5; 
 
        private static final Cache cache = new Cache(); 
 
        private Cache() { 
            new Thread(new ClearCacheThread()).start(); 
        } 
 
        public static Cache getInstance() { 
            return cache; 
        } 
 
        // 每次刷新页面的时候就在缓存中增加一个刷新时间点(标识刷新次数) 
        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_COUNT; 
        } 
 
        // 清理过期数据线程 
        private static class ClearCacheThread implements Runnable { 
            @Override 
            public void run() { 
                while (true) { 
                    try { 
                        // 当页面禁止刷新时让线程睡眠0.6秒钟,防止用户在禁止时还不断刷新.3秒(需要清除5个记录)之后再刷新就可以了 
                        Thread.sleep(600); 
 
                        // 判断当前用户的刷新时间和当前的 系统时间间隔是否超过了闲置时间,如果超过则从缓存中清除记录(就不需要禁止刷新了) 
                        for (String key : map.keySet()) { 
                            CopyOnWriteArrayList<Long> list = map.get(key); 
                            for (Long date : list) { 
                                if (System.currentTimeMillis() - date > Cache.EXPIRE_TIME) { 
                                    System.out.println(list.remove(date)); 
                                } 
                            } 
                        } 
                    } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                    } 
 
                } 
            } 
        } 
    } 
 

上面这段代码其实问题还是很多的,比如如果用户比较多的话,就会有很多的线程存在,线程过多服务器性能肯定会受影响.还有那个CopyOnWriteArrayList性能也不是很高,但是我试了很多的list只有CopyOnWriteArrayList可以实现上述功能,唉,CopyOnWriteArrayList的原理还不是很清楚,如果哪位同仁有高见欢迎拍砖.
 
其实实现这个功能最好的方法是用iptable防火墙来做,但是我没试过.希望有这个经验的可以分享一下.

这篇关于防止用户恶意刷新过滤器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990187

相关文章

如何关闭 Mac 触发角功能或设置修饰键? mac电脑防止误触设置技巧

《如何关闭Mac触发角功能或设置修饰键?mac电脑防止误触设置技巧》从Windows换到iOS大半年来,触发角是我觉得值得吹爆的MacBook效率神器,成为一大说服理由,下面我们就来看看mac电... MAC 的「触发角」功能虽然提高了效率,但过于灵敏也让不少用户感到头疼。特别是在关键时刻,一不小心就可能触

dubbo3 filter(过滤器)如何自定义过滤器

《dubbo3filter(过滤器)如何自定义过滤器》dubbo3filter(过滤器)类似于javaweb中的filter和springmvc中的intercaptor,用于在请求发送前或到达前进... 目录dubbo3 filter(过滤器)简介dubbo 过滤器运行时机自定义 filter第一种 @A

Java 8 Stream filter流式过滤器详解

《Java8Streamfilter流式过滤器详解》本文介绍了Java8的StreamAPI中的filter方法,展示了如何使用lambda表达式根据条件过滤流式数据,通过实际代码示例,展示了f... 目录引言 一.Java 8 Stream 的过滤器(filter)二.Java 8 的 filter、fi

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

redis防止短信恶意调用的实现

《redis防止短信恶意调用的实现》本文主要介绍了在场景登录或注册接口中使用短信验证码时遇到的恶意调用问题,并通过使用Redis分布式锁来解决,具有一定的参考价值,感兴趣的可以了解一下... 目录1.场景2.排查3.解决方案3.1 Redis锁实现3.2 方法调用1.场景登录或注册接口中,使用短信验证码场

Oracle数据库如何切换登录用户(system和sys)

《Oracle数据库如何切换登录用户(system和sys)》文章介绍了如何使用SQL*Plus工具登录Oracle数据库的system用户,包括打开登录入口、输入用户名和口令、以及切换到sys用户的... 目录打开登录入口登录system用户总结打开登录入口win+R打开运行对话框,输php入:sqlp

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Servlet中配置和使用过滤器的步骤记录

《Servlet中配置和使用过滤器的步骤记录》:本文主要介绍在Servlet中配置和使用过滤器的方法,包括创建过滤器类、配置过滤器以及在Web应用中使用过滤器等步骤,文中通过代码介绍的非常详细,需... 目录创建过滤器类配置过滤器使用过滤器总结在Servlet中配置和使用过滤器主要包括创建过滤器类、配置过滤

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置