基于spring的简易访问防刷

再做系统的时候,其实经常会遇上重复请求这个问题,虽然一般前端都会做一些防重复点击的操作,但是,这个玩意儿是没办法防止某些恶性操作的,并且,前端也不一定说就完全屏蔽了用户的重复点击操作。微微研究了一下,搞了一个简易版的防刷系统,不过占用的内存,并发这些玩意儿我还没测试过哦,下面直接贴代码


1.请求拦截器

public class AntiBrushInterceptor implements HandlerInterceptor {

    /**
     * 请求前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //启用简单版防刷
         check = CodeConfig.transfer(AntiBrushCache.simpleCheck(request),request,response);
        return check;
    }

    /**
     * 处理后
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView){
          //获取url
          String url = request.getMethod()+request.getServletPath();
          //获取该次请求的ip
           String ip = Tool.getRealIp(request);
          try{
              AntiBrushCache.url_number.get(url).get(ip).set(0);
          }catch (Exception e){
              logger.error(e);
              if (AntiBrushCache.url_number.get(url) == null){
                  AtomicInteger number = new AtomicInteger();
                  ConcurrentHashMap<String,AtomicInteger> concurrentHashMap = new ConcurrentHashMap<>();
                  concurrentHashMap.put(ip,number);
                  AntiBrushCache.url_number.put(url,concurrentHashMap);
               }
            }
        System.out.println(request.hashCode()+":"+response.getStatus()+":"+System.currentTimeMillis());
    }

    /**
     * 返回后
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }

2.访问控制的具体实现代码

public class AntiBrushCache {

    public static volatile ConcurrentHashMap<String,Integer> url_time = new ConcurrentHashMap<>();

    public static final Boolean check = true;

    /**
     * key --> url
     * value --> {Key--> ip地址 ,value --> 访问累计器}
     */
    public static volatile ConcurrentHashMap<String,ConcurrentHashMap<String,AtomicInteger>> url_number = new ConcurrentHashMap<>();

    /**
     * 监测url是否通过监测
     * @return 200 通过监测,100 不通过
     */
    public static Integer simpleCheck(HttpServletRequest request){
        //获取url
        String url = request.getMethod()+request.getServletPath();
        //获取该请求真实ip
         String ip = Tool.getRealIp(request);
     //获取该ip上次请求时间
     String ip = Tool.getRealIp(request);
     //原子计数器统计访问数值
     AtomicInteger number;
     ConcurrentHashMap<String,AtomicInteger> concurrentHashMap = url_number.get(url);
     if (concurrentHashMap == null){
         synchronized (check){
             if (url_number.get(url) == null){
                 number = new AtomicInteger();
                 concurrentHashMap = new ConcurrentHashMap<>();
                 concurrentHashMap.put(ip,number);
                 url_number.put(url,concurrentHashMap);
             }else{
                 return 100;
             }
         }
     }else{
         number = concurrentHashMap.get(ip);
     }
     number.addAndGet(1);
     //number过大时,则同步访问过快,直接拦截
     if (number.get() >= 2){
         AntiBrushCache.url_number.get(url).get(ip).addAndGet(-1);
         return 100;
     }
     return 200;
   }
}
3:这个拦截系统只要有访问··就会产生记录放在内存,所以··还是要定时清洗下会比较好的


4:启动这个拦截器只需要在spring的配置文件上加上一个拦截器就好了

<!--防刷拦截器-->
<mvc:interceptor>
   <mvc:mapping path="/**" />
   <mvc:exclude-mapping path="/" />
   <mvc:exclude-mapping path="/**/*.html"/>
   <mvc:exclude-mapping path="/**/*.css"/>
   <mvc:exclude-mapping path="/**/*.js"/>
   <mvc:exclude-mapping path="/**/*.png"/>
   <mvc:exclude-mapping path="/**/*.gif"/>
   <mvc:exclude-mapping path="/**/*.jpg"/>
   <mvc:exclude-mapping path="/**/*.jpeg"/>
   <bean class="com.simba.safety.antiBrush.Interceptor.AntiBrushInterceptor"/>
</mvc:interceptor>


猜你喜欢

转载自blog.csdn.net/io277800/article/details/80483007