返回顶部
首页 > 资讯 > 精选 >使用注解怎么实现一个SpringBoot 接口防刷功能
  • 739
分享到

使用注解怎么实现一个SpringBoot 接口防刷功能

2023-06-06 16:06:39 739人浏览 薄情痞子
摘要

这篇文章将为大家详细讲解有关使用注解怎么实现一个SpringBoot 接口防刷功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。项目结构如下:一、编写注解类 AccessLimitpacka

这篇文章将为大家详细讲解有关使用注解怎么实现一个SpringBoot 接口防刷功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

项目结构如下:

使用注解怎么实现一个SpringBoot 接口防刷功能

一、编写注解类 AccessLimit

package cn.mygWEB.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface AccessLimit {    int seconds();    int maxCount();    boolean needLogin() default false;}

二、在Interceptor拦截器中实现拦截逻辑

package cn.mygweb.interceptor;import cn.mygweb.annotation.AccessLimit;import cn.mygweb.entity.Result;import cn.mygweb.entity.StatusCode;import com.alibaba.fastJSON.jsON;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;import java.util.HashMap;import java.util.Map;@Componentpublic class AccessLimitInterceptor extends HandlerInterceptorAdapter {  //模拟数据存储,实际业务中可以自定义实现方式  private static Map<String, AccessInfo> accessInfoMap = new HashMap<>();  @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 needLogin = accessLimit.needLogin();      String key = request.getRequestURI();      //如果需要登录      if (needLogin) {        //获取登录的session进行判断        //……        key += " " + "userA";//这里假设用户是userA,实际项目中可以改为userId      }      //模拟从redis中获取数据      AccessInfo accessInfo = accessInfoMap.get(key);      if (accessInfo == null) {        //第一次访问        accessInfo = new AccessInfo();        accessInfo.setFirstVisitTimestamp(System.currentTimeMillis());        accessInfo.setAccessCount(1);        accessInfoMap.put(key, accessInfo);      } else if (accessInfo.getAccessCount() < maxCount) {        //访问次数加1        accessInfo.setAccessCount(accessInfo.getAccessCount() + 1);        accessInfoMap.put(key, accessInfo);      } else {        //超出访问次数,判断时间是否超出设定时间        if ((System.currentTimeMillis() - accessInfo.getFirstVisitTimestamp()) <= seconds * 1000) {          //如果还在设定时间内,则为不合法请求,返回错误信息          render(response, "达到访问限制次数,请稍后重试!");          return false;        } else {          //如果超出设定时间,则为合理的请求,将之前的请求清空,重新计数          accessInfo.setFirstVisitTimestamp(System.currentTimeMillis());          accessInfo.setAccessCount(1);          accessInfoMap.put(key, accessInfo);        }      }    }    return true;  }    private void render(HttpServletResponse response, String msg) throws Exception {    response.setContentType("application/json;charset=UTF-8");    OutputStream out = response.getOutputStream();    String str = JSON.toJSONString(new Result(true, StatusCode.ACCESSERROR, msg));    out.write(str.getBytes("UTF-8"));    out.flush();    out.close();  }    class AccessInfo {        private long firstVisitTimestamp;        private int accessCount;    public long getFirstVisitTimestamp() {      return firstVisitTimestamp;    }    public void setFirstVisitTimestamp(long firstVisitTimestamp) {      this.firstVisitTimestamp = firstVisitTimestamp;    }    public int getAccessCount() {      return accessCount;    }    public void setAccessCount(int accessCount) {      this.accessCount = accessCount;    }    @Override    public String toString() {      return "AccessInfo{" +          "firstVisitTimestamp=" + firstVisitTimestamp +          ", accessCount=" + accessCount +          '}';    }  }}

三、把Interceptor注册到springboot中

package cn.mygweb.config;import cn.mygweb.interceptor.AccessLimitInterceptor;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorReGIStry;import org.springframework.web.servlet.config.annotation.WebmvcConfigurer;@Configurationpublic class WebConfig implements WebMvcConfigurer {  @Override  public void addInterceptors(InterceptorRegistry registry) {    //注册拦截器    registry.addInterceptor(new AccessLimitInterceptor());  }}

四、在Controller中加入注解实现接口防刷

package cn.mygweb.controller;import cn.mygweb.annotation.AccessLimit;import cn.mygweb.entity.Result;import cn.mygweb.entity.StatusCode;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/access")public class AccessController {  @AccessLimit(seconds = 5, maxCount = 2)//访问控制,5秒内只能访问2次  @GetMapping  public Result access() {    return new Result(true, StatusCode.OK, "访问成功!");  }}

五、测试访问

使用注解怎么实现一个SpringBoot 接口防刷功能

附:StatusCode.java、Result.java、application.yml

StatusCode类

package cn.mygweb.entity;public class StatusCode {  public static final int OK = 20000;//成功  public static final int ERROR = 20001;//失败  public static final int LOGINERROR = 20002;//用户名或密码错误  public static final int ACCESSERROR = 20003;//权限不足  public static final int REMOTEERROR = 20004;//远程调用失败  public static final int REPERROR = 20005;//重复操作  public static final int NOTFOUNDERROR = 20006;//没有对应的抢购数据}

Result类:

package cn.mygweb.entity;import java.io.Serializable;public class Result<T> implements Serializable {  private boolean flag;//是否成功  private Integer code;//返回码  private String message;//返回消息  private T data;//返回数据  public Result(boolean flag, Integer code, String message, Object data) {    this.flag = flag;    this.code = code;    this.message = message;    this.data = (T) data;  }  public Result(boolean flag, Integer code, String message) {    this.flag = flag;    this.code = code;    this.message = message;  }  public Result() {    this.flag = true;    this.code = StatusCode.OK;    this.message = "操作成功!";  }  public boolean isFlag() {    return flag;  }  public void setFlag(boolean flag) {    this.flag = flag;  }  public Integer getCode() {    return code;  }  public void setCode(Integer code) {    this.code = code;  }  public String getMessage() {    return message;  }  public void setMessage(String message) {    this.message = message;  }  public T getData() {    return data;  }  public void setData(T data) {    this.data = data;  }}

applications.yml:

server: port: 8080

关于使用注解怎么实现一个SpringBoot 接口防刷功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 使用注解怎么实现一个SpringBoot 接口防刷功能

本文链接: https://lsjlt.com/news/247815.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 使用注解怎么实现一个SpringBoot 接口防刷功能
    这篇文章将为大家详细讲解有关使用注解怎么实现一个SpringBoot 接口防刷功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。项目结构如下:一、编写注解类 AccessLimitpacka...
    99+
    2023-06-06
  • 详解Springboot如何通过注解实现接口防刷
    目录前言1、实现防刷切面PreventAop.java1.1 定义注解Prevent1.2 实现防刷切面PreventAop2、使用防刷切面3、演示前言 本文介绍一种极简洁、灵活通用...
    99+
    2024-04-02
  • SpringBoot项目中怎么实现接口防刷
    SpringBoot项目中怎么实现接口防刷,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、自定义注解import java.lang.annotation.Rete...
    99+
    2023-06-20
  • 如何使用Redis+Lua脚本实现计数器接口防刷功能
    这篇文章主要介绍如何使用Redis+Lua脚本实现计数器接口防刷功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!【实现过程】一、问题分析 如果set命令设置上,但是在设置失效时间时由于网络抖动等原因导致没...
    99+
    2023-06-29
  • 怎么在HTML5中使用tracking.js实现一个刷脸支付功能
    怎么在HTML5中使用tracking.js实现一个刷脸支付功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。摄像头1.1input获取摄像头html5中获取用户摄像头,有...
    99+
    2023-06-09
  • 怎么用springboot写一个接口
    要使用Spring Boot编写一个接口,可以按照以下步骤进行操作:1. 创建一个Spring Boot项目:可以使用Spring ...
    99+
    2023-10-08
    springboot
  • 怎么在python中使用PyQt5实现一个窗口功能
    怎么在python中使用PyQt5实现一个窗口功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python主要应用领域有哪些1、云计算,典型应用OpenSta...
    99+
    2023-06-14
  • Android应用中怎么实现一个下拉刷新功能
    Android应用中怎么实现一个下拉刷新功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、下拉才出现的视图pull_to_refresh_header.xml<x...
    99+
    2023-05-31
    android roi
  • Redis+Lua脚本实现计数器接口防刷功能(升级版)
    目录【前言】【实现过程】一、问题分析二、解决方案三、代码改造【总结】【前言】 Cash Loan(一):Redis实现计数器防刷 中介绍了项目中应用redis来做计数器的实现过程,最...
    99+
    2024-04-02
  • SpringBoot+Redis怎么实现防止恶意刷新与暴力请求接口
    这篇文章主要介绍“SpringBoot+Redis怎么实现防止恶意刷新与暴力请求接口”,在日常操作中,相信很多人在SpringBoot+Redis怎么实现防止恶意刷新与暴力请求接口问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
    99+
    2023-07-02
  • SpringBoot中怎么实现一个slf4j日志功能
    SpringBoot中怎么实现一个slf4j日志功能,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。其pom.xml里的依赖定义如下:上图看到很多Starter,比如Spri...
    99+
    2023-06-04
  • 怎么在SpringBoot中通过自定义注解实现一个Token校验功能
    本篇文章为大家展示了怎么在SpringBoot中通过自定义注解实现一个Token校验功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。定义Token的注解,需要Token校验的接口,方法上加上此注解...
    99+
    2023-06-14
  • 使用AJAX怎么实现一个注册验证用户名功能
    今天就跟大家聊聊有关使用AJAX怎么实现一个注册验证用户名功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。接口public interface UserDao&...
    99+
    2023-06-07
  • 利用SpringBoot怎么实现一个多表联查功能
    这篇文章给大家介绍利用SpringBoot怎么实现一个多表联查功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。具体方法如下:public interface FieldValueDao extends JpaRepo...
    99+
    2023-05-31
    springboot bo
  • 使用java怎么实现一个ATM功能
    使用java怎么实现一个ATM功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言...
    99+
    2023-06-14
  • 使用springboot怎么样实现一个文件上传下载功能
    这期内容当中小编将会给大家带来有关使用springboot怎么样实现一个文件上传下载功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.文件上传(前端页面):<!DOCTYPE html PUBL...
    99+
    2023-05-31
    springboot bo
  • SpringBoot利用@Retryable注解实现接口重试
    目录前言1.@Retryable是什么2.使用步骤(1) POM依赖(2)启用@Retryable(3)在方法上添加@Retryable(4)@Recover(5)注意事项3.总结前...
    99+
    2024-04-02
  • 使用canvas怎么实现一个手势解锁功能
    使用canvas怎么实现一个手势解锁功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。手势解锁通过手指将屏幕上的九个点依次连接起来形成一个图案,所以叫图案解锁。...
    99+
    2023-06-09
  • 如何使用springboot+vue组件实现接口断言功能
    本文小编为大家详细介绍“如何使用springboot+vue组件实现接口断言功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用springboot+vue组件实现接口断言功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一...
    99+
    2023-07-06
  • 怎么用spring注解开发一个RESTful接口
    本篇内容主要讲解“怎么用spring注解开发一个RESTful接口”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用spring注解开发一个RESTful接口”吧!一、开发REST接口在本专栏...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作