防止用户恶意刷新过滤器

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

相关文章

Mysql中的用户管理实践

《Mysql中的用户管理实践》:本文主要介绍Mysql中的用户管理实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录13. 用户管理13.1 用户 13.1.1 用户信息 13.1.2 创建用户 13.1.3 删除用户 13.1.4 修改用户

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

SpringCloud使用Nacos 配置中心实现配置自动刷新功能使用

《SpringCloud使用Nacos配置中心实现配置自动刷新功能使用》SpringCloud项目中使用Nacos作为配置中心可以方便开发及运维人员随时查看配置信息,及配置共享,并且Nacos支持配... 目录前言一、Nacos中集中配置方式?二、使用步骤1.使用$Value 注解2.使用@Configur

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

Java应用如何防止恶意文件上传

《Java应用如何防止恶意文件上传》恶意文件上传可能导致服务器被入侵,数据泄露甚至服务瘫痪,因此我们必须采取全面且有效的防范措施来保护Java应用的安全,下面我们就来看看具体的实现方法吧... 目录恶意文件上传的潜在风险常见的恶意文件上传手段防范恶意文件上传的关键策略严格验证文件类型检查文件内容控制文件存储

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

防止SpringBoot程序崩溃的几种方式汇总

《防止SpringBoot程序崩溃的几种方式汇总》本文总结了8种防止SpringBoot程序崩溃的方法,包括全局异常处理、try-catch、断路器、资源限制、监控、优雅停机、健康检查和数据库连接池配... 目录1. 全局异常处理2. 使用 try-catch 捕获异常3. 使用断路器4. 设置最大内存和线

9个SpringBoot中的自带实用过滤器使用详解

《9个SpringBoot中的自带实用过滤器使用详解》在SpringBoot应用中,过滤器(Filter)是处理HTTP请求和响应的重要组件,SpringBoot自带了许多实用的过滤器,如字符编码,跨... 目录1. CharacterEncodingFilter - 字符编码过滤器功能和配置手动配置示例2

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils