Spring Boot开发——结合Redis实现接口防止重复提交

news/2025/1/12 9:40:51/

文章目录

  • 一、准备工作
    • 1、引入依赖
    • 2、配置Redis
  • 二、实现代码
    • 1、创建Redis服务类
    • 2、创建AOP切面类
    • 3、自定义注解
    • 4、处理异常
    • 5、使用注解
  • 三、测试验证
    • 1、启动Redis服务
    • 2、启动Spring Boot应用
    • 3、模拟重复提交

在Web开发中,防止用户重复提交表单是一个常见的需求。例如,在用户点击提交按钮后,由于网络延迟或其他原因,用户可能会多次点击,导致数据被重复提交。这不仅会造成数据冗余,还可能引发业务逻辑错误。本文将介绍如何使用Spring Boot结合Redis来实现一个高效的接口防重提交机制。

一、准备工作

1、引入依赖

在Spring Boot项目的pom.xml文件中添加Redis和Spring Data Redis的依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、配置Redis

在application.properties或application.yml文件中配置Redis的连接信息。

spring.redis.host=localhost
spring.redis.port=6379

二、实现代码

1、创建Redis服务类

编写一个Redis服务类,用于操作Redis。这里我们使用Spring Data Redis提供的StringRedisTemplate。

@Service
public class RedisService {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String REPEAT_SUBMIT_KEY_PREFIX = "repeat_submit:";/*** 设置防重提交标识* @param userId 用户ID* @param requestId 请求ID* @param expireTime 过期时间(秒)*/public void setRepeatSubmitKey(String userId, String requestId, long expireTime) {String key = REPEAT_SUBMIT_KEY_PREFIX + userId + ":" + requestId;redisTemplate.opsForValue().set(key, "1", expireTime, TimeUnit.SECONDS);}/*** 检查是否存在防重提交标识* @param userId 用户ID* @param requestId 请求ID* @return 存在返回true,不存在返回false*/public boolean hasRepeatSubmitKey(String userId, String requestId) {String key = REPEAT_SUBMIT_KEY_PREFIX + userId + ":" + requestId;return redisTemplate.hasKey(key);}
}

2、创建AOP切面类

编写一个AOP切面类,用于拦截需要防重提交的接口,并在执行前检查Redis中是否存在防重提交标识。

@Aspect
@Component
public class RepeatSubmitAspect {@Autowiredprivate RedisService redisService;@Before("@annotation(RepeatSubmit)")public void beforeMethod(JoinPoint joinPoint, RepeatSubmit repeatSubmit) throws Throwable {// 获取当前用户ID和请求ID(这里假设通过ThreadLocal获取,实际项目中可能通过Session、JWT等方式获取)String userId = "当前用户ID"; // 替换为实际获取用户ID的代码String requestId = UUID.randomUUID().toString(); // 使用UUID作为请求ID// 检查Redis中是否存在防重提交标识if (redisService.hasRepeatSubmitKey(userId, requestId)) {throw new RepeatSubmitException("请勿重复提交");}// 设置防重提交标识(设置过期时间,如60秒)redisService.setRepeatSubmitKey(userId, requestId, repeatSubmit.expireTime());}
}

3、自定义注解

创建一个自定义注解@RepeatSubmit,用于标记需要防重提交的接口。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatSubmit {long expireTime() default 60; // 默认过期时间60秒
}

4、处理异常

创建一个自定义异常RepeatSubmitException,用于在检测到重复提交时抛出。

public class RepeatSubmitException extends RuntimeException {public RepeatSubmitException(String message) {super(message);}
}

5、使用注解

在需要防重提交的接口上使用@RepeatSubmit注解。

@RestController
@RequestMapping("/api")
public class DemoController {@PostMapping("/submit")@RepeatSubmit(expireTime = 60)public ResponseEntity<String> submit(@RequestBody DemoRequest request) {// 业务逻辑处理return ResponseEntity.ok("提交成功");}
}

三、测试验证

1、启动Redis服务

确保Redis服务已启动并运行。

2、启动Spring Boot应用

运行Spring Boot应用,访问需要防重提交的接口。

3、模拟重复提交

使用postman等测试工具在接口响应前多次点击提交按钮,观察是否抛出RepeatSubmitException异常。


http://www.ppmy.cn/news/1562462.html

相关文章

Hadoop高可用集群搭建

在三台虚拟机上搭建具有两个NameNode节点和两个ResourceManager节点的Hadoop高可用集群。步骤如下&#xff1a; 1.在3台虚拟机中的/export/servers目录中创建目录hadoop-HA&#xff0c;用于存放部署Hadoop高可用集群的Hadoop安装目录&#xff0c;命令如下&#xff1a; 2.安装H…

JavaWeb—Servlet详解

前言&#xff1a; 本章节主要学习Servlet基础知识点&#xff0c;收录于JavaWeb系列&#xff0c;该系列主要讲解Servlet、JSP、Filter过滤器、Session、分层开发概念等知识点&#xff0c;欢迎童鞋们互相交流。觉得不错可以三连订阅喔。 目标&#xff1a; 一、概念 二、入门程…

【灵码助力安全2】——利用通义灵码辅助复现未公开漏洞的实践

前言 暨上一篇【灵码助力安全1】——利用通义灵码辅助快速代码审计的最佳实践之后&#xff0c;这第二篇主要是想分享一下通义灵码在复现未公开漏洞方面的应用&#xff0c;当然&#xff0c;前提也是必须得有相应的源码。 有的时候&#xff0c;由于安全人员水平的限制和时间、…

Redis 三大问题:缓存穿透、缓存击穿、缓存雪崩

Redis 作为高性能的内存数据库&#xff0c;广泛应用于缓存场景。然而&#xff0c;在实际使用中&#xff0c;可能会遇到三大经典问题&#xff1a;缓存穿透、缓存击穿 和 缓存雪崩。这些问题如果不加以解决&#xff0c;可能会导致系统性能下降甚至崩溃。 1. 缓存穿透 问题描述 …

ChatGPT 网络配置问题解决方案

随着人工智能技术的飞速发展&#xff0c;基于GPT架构的聊天机器人&#xff0c;如ChatGPT&#xff0c;已经在多个领域获得了广泛应用。其强大的自然语言处理能力为用户带来了便捷的交互体验。然而&#xff0c;在实际使用过程中&#xff0c;尤其是在部署和访问时&#xff0c;用户…

自动化之数据库:docker部署mongo,为下一步的使用打下基础

以下是一个详细的Docker Compose配置示例&#xff0c;用于设置一个包含三个节点的MongoDB副本集&#xff0c;并确保安全性&#xff08;使用账号密码进行认证&#xff09;。所有节点都将设置在同一个Docker网络&#xff08; py-mongo &#xff09;下&#xff0c;以便于未来的扩…

你知道APP是怎么开发的吗?

你知道APP是怎么开发的吗&#xff1f; 你知道APP是怎么开发的吗&#xff1f;如何将开发完成的APP发布在应用市场&#xff1f;如何在阿里云上实现一站式App的开发、测试、运维、运营&#xff1f; 你知道APP是怎么开发的吗&#xff1f; 作为后端开发者&#xff0c;尽管我的主要工…

数据结构——查找二叉树

二叉搜索树的概念 如图所示&#xff0c;二叉搜索树&#xff08;binary search tree&#xff09;满足以下条件。 对于根节点&#xff0c;左子树中所有节点的值 < 根节点的值 < 右子树中所有节点的值。任意节点的左、右子树也是二叉搜索树&#xff0c;即同样满足条件 1. …