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

文章目录

  • 一、准备工作
    • 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的依赖。

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、配置Redis

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

java 复制代码
spring.redis.host=localhost
spring.redis.port=6379

二、实现代码

1、创建Redis服务类

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

java 复制代码
@Service
public class RedisService {

    @Autowired
    private 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中是否存在防重提交标识。

java 复制代码
@Aspect
@Component
public class RepeatSubmitAspect {

    @Autowired
    private 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,用于标记需要防重提交的接口。

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

4、处理异常

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

java 复制代码
public class RepeatSubmitException extends RuntimeException {
    public RepeatSubmitException(String message) {
        super(message);
    }
}

5、使用注解

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

java 复制代码
@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异常。

相关推荐
clk66073 小时前
Spring Boot
java·spring boot·后端
爱敲代码的TOM3 小时前
基于JWT+SpringSecurity整合一个单点认证授权机制
spring boot
MuYiLuck3 小时前
【redis实战篇】第八天
数据库·redis·缓存
loser.loser3 小时前
QQ邮箱发送验证码(Springboot)
java·spring boot·mybatis
�FENG4 小时前
Redis 安装配置和性能优化
redis·持久化
喜欢踢足球的老罗4 小时前
在Spring Boot 3.3中使用Druid数据源及其监控功能
java·spring boot·后端·druid
weixin_436525075 小时前
Spring Boot 实现流式响应(兼容 2.7.x)
java·spring boot·后端
weixin_429326096 小时前
Spring Boot-面试题(52)
java·spring boot·后端
暴躁哥6 小时前
Spring Boot 类加载机制深度解析
spring boot·后端·类加载机制
qq_338032926 小时前
Spring Boot/Spring应用中配置自定义RedisTemplate
spring boot·redis·spring