首页 > 数据库 >SpringBoot Redis使用AOP防止重复提交

SpringBoot Redis使用AOP防止重复提交

时间:2023-09-17 15:33:13浏览次数:38  
标签:lang count SpringBoot AOP Redis org import annotation 请求

自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * @ProjectName: gswr-ets-cloud
 * @ClassName:
 * @Description: 防止重复提交的自定义注解
 * @Date: 2022-2-8 9:28
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
    int seconds();
    int maxCount();
}
防止重复请求切面
import com.alibaba.fastjson.JSONObject;
import io.renren.commons.tools.utils.Result;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @ProjectName: gswr-ets-cloud
 * @ClassName:
 * @Description: 防止重复请求
 * @Date: 2022-2-8 11:12
 */
@Aspect
@Component
public class NoRepeatSubmitAspect {

    protected Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(noRepeatSubmit)")
    public void pointCut(NoRepeatSubmit noRepeatSubmit) {
    }

    @Around("pointCut(noRepeatSubmit)")
    public Result around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
        ServletRequestAttributes ra= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ra.getRequest();
        Assert.notNull(request, "request can not null");

        int seconds = noRepeatSubmit.seconds();
        int maxCount = noRepeatSubmit.maxCount();
        //获取请求Ip
        String ip=request.getRemoteAddr();
        //将请求路径及ip组成键值 如:/finance/fastApply/test:192.168.56.1
        String key = request.getServletPath() + ":" + ip ;
        //获取请求次数
        Integer count = (Integer) redisTemplate.opsForValue().get(key);

        if (null == count) {//第一次访问
            redisTemplate.opsForValue().set(key, 1,seconds, TimeUnit.SECONDS);
            pjp.proceed();
            return new Result().ok("第一次请求成功");
        }else if (count < maxCount) {//在允许的访问次数内
            count = count+1;
            redisTemplate.opsForValue().set(key, count,0);
            pjp.proceed();
            return new Result().ok("请求成功");
        }else  {//超出访问次数
            logger.info("访问过快ip ===> " + ip + " 且在 " + seconds + " 秒内超过最大限制 ===> " + maxCount + " 请求次数达到 ===> " + count);
            return new Result().error("请求过快");
        }
    }
}


使用样例
	/**
     * 测试重复提交 30s内允许请求1次
     */
    @NoRepeatSubmit(seconds=30, maxCount=1)
    @GetMapping("/test")
    public Result test()
    {
        System.out.println("我被请求了");
        return new Result().ok("请求成功");
    }

此方法只是简单的根据记录同一IP提交次数去防止重复请求

标签:lang,count,SpringBoot,AOP,Redis,org,import,annotation,请求
From: https://blog.51cto.com/u_16258535/7502248

相关文章

  • 快速搭建SpringBoot3.x项目
    写在前面上一小节中我们从0到1使用Vite搭建了一个Vue3项目,并集成了ElementPlus实现了一个简单的增删改查页面。这一篇中我们将使用IDEA快速搭建一个SpringBoot3.x的项目。一、创建项目1、File->new->project2、选择“SpringInitializr”,点击next;3、选择springboot版......
  • SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据
    一、背景:    利用ThreadPoolTaskExecutor多线程异步批量插入,提高百万级数据插入效率。ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。ThreadPoolTaskExecutor是ThreadPoolExecutor的封装,所以,性能更加优秀,推荐ThreadPoolTaskExecutor。二、具体细节:2.1、配置app......
  • redis该怎么用
    最近一些人在介绍方案时,经常会出现redis这个词,于是很多小伙伴百度完redis也就觉得它是一个缓存,然后项目里面把数据丢进去完事,甚至有例如将实体属性拆分塞进redishash里面的奇怪用法等等!原因是什么呢?大家觉得redis火,使用了redis项目就是高大上的,于是不管三七二十一,项目里用上强塞一......
  • springboot+html使用sql语句能够在控制台输出相关数据信息list,但是输出的list=null(未
    问题描述具体来说,就是,连接上数据库之后,发现查询的sql语句能够正常在控制台输出数据,但是将sql语句的查询结果放到list里面,在控制台输出的list=[null];真的崩溃了!!!之前从来没有遇到过这种情况;尝试了网上的各种方法,也都解决不了,麻木ing~求解!......
  • Redis急速说明
    Redis急速部署前言:需求的出现在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原因是因为那时候Web站点基本上访问和并发不高、交互也较少。而在后来,随着访问量的提升,使用关系型数据库的Web站点多多少少都开始在性能上出现了一些瓶颈,而瓶颈的源头一般是在磁盘......
  • springboot安卓音乐播放器
    开发环境及工具:大等于jdk1.8,大于mysql5.5,idea(eclipse),AndroidStudio技术说明:springbootmybatisandroid代码注释齐全,没有多余代码,适合学习(毕设),二次开发,包含论文技术相关文档。功能介绍:用户端:登录注册首页显示搜索音乐,轮播图,音乐列表点击音乐进入音乐详情(以及展示评论信息),可以点......
  • springboot自动配置
    SpringBoot的自动配置功能非常强大,可以大大简化应用程序的配置。下面是一个简单的SpringBoot自动配置的例子:假设我们有一个名为@EnableMyAutoConfiguration的自定义自动配置类,其中包含一个名为@MyBean的自定义Bean:@Configuration@EnableMyAutoConfigurationpubliccl......
  • springboot vue uniapp 小说电子书阅读小程序APP源码
    开发环境及工具:大等于jdk1.8,大于mysql5.5,idea(eclipse),nodejs,vscode(webstorm),HBuilderX技术说明:springbootmybatisvueelementuiuniapp代码注释齐全,没有多余代码,适合学习(毕设),二次开发,包含论文技术相关文档。功能介绍:用户端:登录注册首页显示搜索小说,轮播图,最新发布小说(可带推荐算......
  • 在CentOS上安装Redis-cli工具
    如果你想在CentOS上安装Redis-cli工具,可以按照以下步骤进行操作:1.安装Redis依赖包:在命令行中执行以下命令安装Redis依赖包:```sudoyuminstallgccmake```2.下载Redis源代码包:从Redis官网(https://redis.io/download)下载最新的Redis源代码包。3.解压源代码包:将下载的Redis......
  • SpringBoot + Redis + Token 解决接口幂等性问题
    前言SpringBoot实现接口幂等性的方案有很多,其中最常用的一种就是token+redis方式来实现。下面我就通过一个案例代码,帮大家理解这种实现逻辑。原理前端获取服务端getToken()->前端发起请求->header中带上token->服务端校验前端传来的token和redis中的token是否......