需求:有的时候我们提供给别人接口,但是一般客户并不知道接口的频繁的调用会给服务器带来很大的运行消耗,所以会有频繁请求接口的情况,甚至两次请求的时间间隔都不超过1秒钟,这个时候我们针对同一个用户频繁的请求接口可以进行拦截来告诉用户请求接口过于频繁请稍后请求....

实现上面的需求,我们可能会想到利用缓存的机制

比如用户这次请求,我们存入到缓存中,并且设置一定的保存时间,在这段时间内,如果该用户再一次的请求接口,提示用户请求太过于频繁

针对用户的请求我们可以选择在过滤器中实现这个功能

首先是配置过滤器:

     <filter><filter-name>CorsFilter</filter-name><filter-class>com.hangxin.xxrest.filter.CORSFilter</filter-class></filter><filter-mapping><filter-name>CorsFilter</filter-name><url-pattern>/rest/*</url-pattern></filter-mapping>

在web.xml配置过滤器,也是就调用以/rest/*结尾的请求接口的时候都会进入该拦截器

我们看看拦截器这个核心应该怎么来编写:

package com.hangxin.xxrest.filter;import java.io.IOException;
import java.io.PrintWriter;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 net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import net.sf.json.JSONObject;public class CORSFilter implements Filter {private static Cache cache = new Cache("filter", 100, false, false, 60, 10, false, 0);@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) servletResponse;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "GET,POST,HEAD,PUT,DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "Accept,Origin,X-Requested-With,Content-Type,X-Auth-Token");response.setHeader("Access-Control-Allow-Credentials", "true");HttpServletRequest request = (HttpServletRequest) servletRequest;String applyip = request.getRemoteHost();String applymethod = request.getRequestURI();String cname = applyip + applymethod;if (cache.getQuiet(cname) != null) {JSONObject jsonRtn = new JSONObject();jsonRtn.put("code", "9999");jsonRtn.put("msg", "接口请求过于频繁,请休息一下.....");PrintWriter out = response.getWriter();out.print(jsonRtn.toString());} else {Element element = new Element(cname, 1);cache.put(element);chain.doFilter(servletRequest, servletResponse);}}@Overridepublic void destroy() {}}

重点:

首先是创建一个静态的缓存:

private static Cache cache = new Cache("filter", 100, false, false, 60, 10, false, 120);

我们说说一下这个构造函数(有很多,我捡了一个简单的使用)

net.sf.ehcache.Cache.Cache(String name, int maxElementsInMemory, boolean overflowToDisk, boolean eternal, long timeToLiveSeconds, long timeToIdleSeconds, boolean diskPersistent, long diskExpiryThreadIntervalSeconds)

第一个是name:也就是缓存的名称,这个是结合的是缓存管理器 cacheManeger 这个类进行使用

maxElementsInMemory:这个是换存中最大存储的元素的个数

overflowToDisk:如果说缓存中元素的个数太多了怎么处理,true存入到写入到磁盘

eternal:标识的是是否持久化,如果说是true标识的是持久化,如果为false标识不持久化,如果选择持久化这样timeToLiveSeconds 和 timeToIdleSeconds 字段就没用了

timeToLiveSeconds 元素在缓存中保存的时间

timeToIdleSeconds 元素在缓存中的最大的空闲时间,如果大于空闲时间,元素会被清除

diskPersistent:设定在虚拟机重启时是否进行磁盘存储,默认为false

diskExpiryThreadIntervalSeconds  磁盘中的文件是否过期,检验的频率 时间间隔

String applyip = request.getRemoteHost();
        String applymethod = request.getRequestURI();
        String cname = applyip + applymethod;

if (cache.getQuiet(cname) != null) {
            JSONObject jsonRtn = new JSONObject();
            jsonRtn.put("code", "9999");
            jsonRtn.put("msg", "接口请求过于频繁,请休息一下.....");
            PrintWriter out = response.getWriter();
            out.print(jsonRtn.toString());
        } else {
            Element element = new Element(cname, 1);
            cache.put(element);
            chain.doFilter(servletRequest, servletResponse);

}

我可以获取到请求方的地址和请求的方法

首先判断缓存中是否存在,如果缓存中存在则是因为请求过于频繁

如果缓存中不存在,将其存入到缓存中,并且调用接口方法

上面主要是缓存的一个小小的应用吧

希望对你有所帮助

查看原文:

用缓存拦截接口频繁的请求相关推荐

  1. Okhttp 插入缓存拦截器 解析

    我们在做网络请求的时候,如果网络请求过于频繁而且请求的数据变动不大,或者基本没有变动,这个时候如果没有缓存功能,我们想一下 会浪费掉多少资源,一次请求刷新一次,去请求一次,不但会消耗用户的流量,而且还 ...

  2. core api其他电脑不能访问接口_第 12 篇:加缓存为接口提速

    作者:HelloGitHub-追梦人物 目前,用户对于接口的操作基本都需要查询数据库.获取文章列表需要从数据库查询,获取单篇文章需要从数据库查询,获取评论列表也需要查询数据.但是,对于博客中的很多资源 ...

  3. 修改拦截器里的请求头_OkHttp4 源码分析(1) 请求流程分析

    square/okhttp​github.com 本文基于OkHttp4.7.1分析 同步请求示例代码 OkHttpClient client = new OkHttpClient.Builder() ...

  4. java抢购防止多次请求_springboot项目中接口防止恶意请求多次

    springboot项目中接口防止恶意请求多次 在项目中,接口的暴露在外面,很多人就会恶意多次快速请求,那我们开发的接口和服务器在这样的频率下的话,服务器和数据库很快会奔溃的,那我们该怎么防止接口防刷 ...

  5. LindAgile~缓存拦截器支持类的虚方法了

    写它的原因 之前写过一个缓存拦截器,主要在方法上添加CachingAspect特性之后,它的返回值就可以被缓存下来,下次访问时直接从缓存中返回结果,而它有一个前提,就是你的方法需要是一个接口方法,缓存 ...

  6. springboot项目中接口防止恶意请求多次,重复请求的解决办法,适合小白

    在项目中,接口的暴露在外面,很多人就会恶意多次快速请求,那我们开发的接口和服务器在这样的频率下的话,服务器和数据库很快会奔溃的,那我们该怎么防止接口防刷呢?由于博主小白,很多都不懂,都是从网上一点一点 ...

  7. java接口 密钥签名作用_api接口签名加密请求(二)

    在"api接口签名加密请求,从springmvc4项目搭建开始"篇文章,讲述了使用java springmvc搭建api接口请求例子.为了方便php能调用,接着写了php的demo ...

  8. 自定义MyHttpServletRequest解决过滤器拦截@RequestBody整体JSON请求问题

    自定义MyHttpServletRequest解决过滤器拦截@RequestBody整体JSON请求问题 参考文章: (1)自定义MyHttpServletRequest解决过滤器拦截@Request ...

  9. php 请求拦截,解决拦截器对ajax请求的拦截实例详解

    解决拦截器对ajax请求的的拦截 拦截器配置:public boolean preHandle(HttpServletRequest request, HttpServletResponse resp ...

最新文章

  1. java工作流引擎证照库类型的流程设计 实现方案与演示案例
  2. Windows下Eclipse和PyDev搭建完美Python开发环境
  3. 【转】flannel网络的VXLAN及host-gw
  4. 1132:石头剪子布
  5. 【华为大咖分享】10.DevOps敏捷测试之道(后附PPT下载地址)
  6. Redis的服务端启动和客户端连接
  7. 金山毒霸免费Wifi独立版,只需一块无线网卡,完爆360随身wifi
  8. mysql用utf-8_为什么在MySQL中不建议使用UTF-8
  9. 【期末划重点】高数下期末考复习
  10. oracle solaris 10 是什么,Oracle Solaris 10 操作系统
  11. 中国城市新分级名单(转)
  12. 【色彩管理】CMYK色彩模式详解
  13. 基于量子计算的md5密码哈希破解方法
  14. +initialize方法的调用时机
  15. 【期末大作业】公益网站ps平面设计
  16. Java实现 蓝桥杯 算法训练 Beaver's Calculator
  17. 小程序API的Promise化
  18. 教你如何在腾讯云阿里云薅羊毛
  19. cocos3D 教程
  20. 【紫光同创国产FPGA教程】【第四章】PDS下PLL实验

热门文章

  1. js在PageOffice打开的Word文档光标处插入书签
  2. Asp.net MVC 3实例学习之ExtShop(二)——创建母版页
  3. 水晶报表printmode的ActiveX打印
  4. 再见 FTP/SFTP,是时候拥抱下一代文件传输利器 Croc 了!
  5. Redis 面试连环炮,看看你能撑到哪一步?
  6. 基于MySQL数据库下亿级数据的分库分表
  7. 一次 HashSet 所引起的并发问题
  8. 深度工作,打工人的必备指南!
  9. 什么是OKR?目标管理如何做?
  10. leangoo里怎么邀请成员加入看板?