• 首先是写一个注解类

  • 拦截器中实现

  • 注册到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. Java逆变(Covariant)和协变(Contravariant)

    1. 定义 逆变和协变描述的经过类型变换后的类型之间的关系.假如A和B表示类型,f表示类型变换,A ≤B表示A是B的子类型,那么 如果A ≤B,f(A) ≤f(B),那么f是协变 如果A ≤B,f(B ...

  2. new String("123") 创建了几个对象?

    String 对象可谓再熟悉不过了,与此相关的面试题经常会引出内存性能优化的问题,本篇主要以 new String("123") 创建了几个对象为例记录. 一.你能回答正确吗 St ...

  3. [React] Fetch Data with React Suspense

    Let's get started with the simplest version of data fetching with React Suspense. It may feel a litt ...

  4. CCF 201909-5 城市规划

    试题编号: 201909-5 试题名称: 城市规划 时间限制: 3.0s 内存限制: 512.0MB 问题描述: 几乎是Gym102222G的原版,详解见上一篇博文 /* 贡献+树形dp+01背包 * ...

  5. mac 以多tab的方式打开

    让mac 始终以多tab的方式打开程序 背景: 开发中始终需要多个 项目 的方式进行处理, 但一直使用 `command + `` 的方式总是比较烦人, 有没有一个比较好的视图方式呢; 即我想在一个窗 ...

  6. xcode7: Undefined symbols for architecture i386: "_iconv_open", referenced from:

    在整合cocos和quick时,出现这个错误,我按照以前的方法 link binary with libraries 中add libiconv.2.dylib ,发现已经没有了这个库. 网上找了一下 ...

  7. 使用MeadCo's ScriptX控件做WEB打印

    官方网址:http://www.meadroid.com/scriptx/index.asp MeadCo's ScriptX控件有两种使用方式,一种是做为免费版本使用,一种是做为收费版本使用,免费版 ...

  8. 第08组 Beta冲刺(3/4)

    队名 八组评分了吗 组长博客链接(2分) 组员1李昕晖(组长) 过去两天完成了哪些任务 文字/口头描述 了解各个小组的进度与难以攻破的地方,晚上安排开会,安排新的冲刺任务. 重新分配小组及个人任务. ...

  9. 5G网络类型 ?

    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SE ...

  10. HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型

    HandlerMethodArgumentResolver SpringMVC 参数解析 继承关系以及各解析器解析类型 I HandlerMethodArgumentResolver (org.spr ...