• 首先是写一个注解类

  • 拦截器中实现

  • 注册到springboot中

  • 在Controller中加入注解

  • 说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springboot的基本知识,redis基本操作,

    首先是写一个注解类:

  • import java.lang.annotation.Retention;
    import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.RetentionPolicy.RUNTIME; /**
    * @author yhq
    * @date 2018/9/10 15:52
    */ @Retention(RUNTIME)
    @Target(METHOD)
    public @interface AccessLimit { int seconds();
    int maxCount();
    boolean needLogin()default true;
    }

    拦截器

    import com.alibaba.fastjson.JSON;
    import com.example.demo.action.AccessLimit;
    import com.example.demo.redis.RedisService;
    import com.example.demo.result.CodeMsg;
    import com.example.demo.result.Result;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.OutputStream; /**
    * @author yhq
    * @date 2018/9/10 16:05
    */ @Component
    public class FangshuaInterceptor extends HandlerInterceptorAdapter { @Autowired
    private RedisService redisService; @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //判断请求是否属于方法的请求
    if(handler instanceof HandlerMethod){ HandlerMethod hm = (HandlerMethod) handler; //获取方法中的注解,看是否有该注解
    AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
    if(accessLimit == null){
    return true;
    }
    int seconds = accessLimit.seconds();
    int maxCount = accessLimit.maxCount();
    boolean login = accessLimit.needLogin();
    String key = request.getRequestURI();
    //如果需要登录
    if(login){
    //获取登录的session进行判断
    //.....
    key+=""+"1"; //这里假设用户是1,项目中是动态获取的userId
    } //从redis中获取用户访问的次数
    AccessKey ak = AccessKey.withExpire(seconds);
    Integer count = redisService.get(ak,key,Integer.class);
    if(count == null){
    //第一次访问
    redisService.set(ak,key,1);
    }else if(count < maxCount){
    //加1
    redisService.incr(ak,key);
    }else{
    //超出访问次数
    render(response,CodeMsg.ACCESS_LIMIT_REACHED); //这里的CodeMsg是一个返回参数
    return false;
    }
    } return true; }
    private void render(HttpServletResponse response, CodeMsg cm)throws Exception {
    response.setContentType("application/json;charset=UTF-8");
    OutputStream out = response.getOutputStream();
    String str = JSON.toJSONString(Result.error(cm));
    out.write(str.getBytes("UTF-8"));
    out.flush();
    out.close();
    }
    }

    注册到springboot中

    import com.example.demo.ExceptionHander.FangshuaInterceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /**
    * @author yhq
    * @date 2018/9/10 15:58
    */
    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter { @Autowired
    private FangshuaInterceptor interceptor; @Override
    public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(interceptor);
    }
    }

    在Controller中加入注解

  • import com.example.demo.result.Result;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody; /**
    * @author yhq
    * @date 2018/9/10 15:49
    */ @Controller
    public class FangshuaController { @AccessLimit(seconds=5, maxCount=5, needLogin=true)
    @RequestMapping("/fangshua")
    @ResponseBody
    public Result<String> fangshua(){ return Result.success("请求成功"); }

    相关参考:https://www.jianshu.com/p/364a6f466a2a

Spring Boot 项目的 API 接口防刷的更多相关文章

  1. Spring Boot项目的Logback配置文件使用yaml格式

    1.普通的Spring项目使用logback默认用properties文件做为配置变量. 2.如果非要用yaml文件,那么可以转成Spring Boot项目,天生无缝结合 3.没办法,如果项目配置文件 ...

  2. 一行配置搞定 Spring Boot项目的 log4j2 核弹漏洞!

    相信昨天,很多小伙伴都因为Log4j2的史诗级漏洞忙翻了吧? 看到群里还有小伙伴说公司里还特别建了800+人的群在处理... 好在很快就有了缓解措施和解决方案.同时,log4j2官方也是速度影响发布了 ...

  3. 提升Spring Boot项目中API接口并发能力的一个注解,效果明显

    异步调用几乎是处理高并发Web应用性能问题的万金油,那么什么是"异步调用"?"异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次 ...

  4. spring boot项目的maven库查询地址

    阿里巴巴地址 http://maven.aliyun.com/nexus/#welcome maven通用地址 http://mvnrepository.com/ gradle默认mavenCentr ...

  5. Spring Boot实现通用的接口参数校验

    Spring Boot实现通用的接口参数校验 Harries Blog™ 2018-05-10 2418 阅读 http ACE Spring App API https AOP apache IDE ...

  6. Spring Boot Hello World (restful接口)例子

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  7. 使用Redis+自定义注解实现接口防刷

    最近开发了一个功能,需要发送短信验证码鉴权,考虑到短信服务需要收费,因此对此接口做了防刷处理,实现方式主要是Redis+自定义注解(需要导入Redis的相关依赖,完成Redis的相关配置,gs代码,这 ...

  8. Spring Boot项目的接口防刷

    说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springboot的基本知识,redis基本操作, 首先是写一个注解类: import java.lang.an ...

  9. swagger ui和spring boot集成生成api文档

    作者:小莫链接:https://www.zhihu.com/question/28119576/answer/134580038来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

随机推荐

  1. Codeforces Round #603 (Div. 2) A. Sweet Problem(数学)

    链接: https://codeforces.com/contest/1263/problem/A 题意: You have three piles of candies: red, green an ...

  2. MongoDB索引存储BTree与LSM树(转载)

    1.为什么 MongoDB 使用B-树,而不是B+树 MongoDB 是一种 nosql,也存储在磁盘上,被设计用在数据模型简单,性能要求高的场合.性能要求高,我们看B-树与B+树的区别: B+树内节 ...

  3. luoguP1742 最小圆覆盖

    最小圆覆盖 首先 没错,我是个蒟蒻.luogu 流程 圆 C; for(i=1 to n) { if(P[i] 不在 C 内) { C = {P[i], 0}; for(j=1 to i-1) { i ...

  4. JAVA基础--环境搭建

    概况 系统:win10 企业版 IDE:Eclipse 4.7.3 JDK:jdk1.8.0_171 数据库:SQLServer2012 Oracle,未安装MySQL 安装 JDK与开发工具(Ecl ...

  5. x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式

    目录 x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式 一丶x86指令复习. 1.1什么是x86指令. 1.2 x86与x64下的通用寄存器 1.3 OpCode 1.4 7种寻址方式 二 ...

  6. python 项目实战之装饰器

    import logging def use_logging(func): def writelog(*args, **kwargs): logging.warning("%s is run ...

  7. 深度学习中loss总结

    一.分类损失 1.交叉熵损失函数 公式: 交叉熵的原理 交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近.假设概率分布p为期望输出,概率分布q为实际输 ...

  8. ruby-on-rails-BUG

    Ruby on Rails errors: (新手期) rails 自动化部署教程 Q1: rvm 无法使用 $ rvm use 1.9.3 --default RVM is not a functi ...

  9. 【转】Spring Boot @Condition 注解,组合条件你知道吗

    原文:https://www.cnblogs.com/FraserYu/p/11280420.html 上一篇文章 你应该知道的 @ConfigurationProperties 注解的使用姿势,这一 ...

  10. 域名解析前面的前缀* @ www 分别代表什么

    www 是指域名前带 www的,以百度为例,就是 www.baidu.com@ 是指前面不带任何主机名的,以百度为例,就是 baidu.com* 是指泛解析,是指除已添加的解析记录以外的所有主机都以此 ...