Shaw0xyz 发表于 2024-6-13 14:30:25

SpringBoot+AOP+注解+Redis防重复提交

本帖最后由 Shaw0xyz 于 2024-6-13 14:42 编辑

1. 引言
   在Web开发中,防止重复提交是一个常见的需求。重复提交可能导致数据的不一致或者业务逻辑的混乱,因此有必要在系统中加入相应的机制来处理这个问题。本文将介绍如何利用Spring Boot结合AOP和Redis来实现一个有效的防重复提交的解决方案。

1.1. 问题背景
   在Web应用程序中,用户可能会多次点击提交按钮或者多次发送同一个请求,这可能导致系统执行同一操作多次,例如重复支付、重复下单等,从而产生不良影响。

1.1.1. 传统解决方案
   传统的解决方案通常是通过前端JavaScript来控制提交按钮的禁用状态或者在后端通过记录请求的状态来防止重复提交。但这些解决方案都有其局限性,比如JavaScript禁用按钮无法完全防止用户通过其他手段提交数据。

2. 技术方案

2.1. 使用Spring Boot和AOP
   Spring Boot是一个快速开发Spring应用程序的框架,而AOP(面向切面编程)可以很好地与Spring Boot集成,用于处理横切关注点,如日志、事务等。我们可以利用AOP来实现对请求的拦截和处理。

2.1.1. 定义注解
   首先,我们需要定义一个自定义注解 `@NoRepeatSubmit`,用于标记需要防止重复提交的方法或者Controller中的请求处理方法。

   import java.lang.annotation.ElementType;
   import java.lang.annotation.Retention;
   import java.lang.annotation.RetentionPolicy;
   import java.lang.annotation.Target;

   @Target(ElementType.METHOD)
   @Retention(RetentionPolicy.RUNTIME)
   public @interface NoRepeatSubmit {
   }
2.1.2. 编写AOP切面
   创建一个AOP切面类,通过方法拦截和Redis缓存来实现防重复提交的逻辑。

   import org.aspectj.lang.annotation.Aspect;
   import org.aspectj.lang.annotation.Before;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.data.redis.core.StringRedisTemplate;
   import org.springframework.stereotype.Component;
   import java.util.concurrent.TimeUnit;

   @Aspect
   @Component
   public class NoRepeatSubmitAspect {

       @Autowired
       private StringRedisTemplate redisTemplate;

       @Before("@annotation(noRepeatSubmit)")
       public void before(NoRepeatSubmit noRepeatSubmit) {
         // 获取请求的URI作为缓存的key
         String key = getRequestUri();

         // 如果缓存中存在相同的key,则表示重复提交
         if (redisTemplate.opsForValue().setIfAbsent(key, "", 10, TimeUnit.SECONDS)) {
               throw new RuntimeException("请勿重复提交!");
         }
       }

       private String getRequestUri() {
         // 省略获取请求URI的实现,可以根据具体情况获取
         return null;
       }
   }
   在上述代码中,我们利用了Redis的setIfAbsent方法来实现对请求的幂等性校验,有效防止了重复提交。

2.1.3. 在Controller中使用注解
   在需要防止重复提交的Controller的请求处理方法上添加 `@NoRepeatSubmit` 注解即可生效。

   import org.springframework.web.bind.annotation.PostMapping;
   import org.springframework.web.bind.annotation.RestController;

   @RestController
   public class TestController {

       @NoRepeatSubmit
       @PostMapping("/test")
       public String test() {
         // 处理业务逻辑
         return "success";
       }
   }

2.1.4. 配置Redis
   在Spring Boot的配置文件中配置Redis连接信息,确保AOP切面能够正确地使用Redis作为缓存存储。

3. 总结
   本文介绍了如何利用Spring Boot结合AOP和Redis来实现一个简单而有效的防重复提交的解决方案。通过定义自定义注解、编写AOP切面以及利用Redis缓存,我们可以有效地防止用户在Web应用中多次提交相同的请求,从而保证系统的数据一致性和业务逻辑的正确性。





/ 荔枝学姐de课后专栏 /

Hi!这里是荔枝学姐~

欢迎来到我的课后专栏

自然语言学渣 NLP摆烂姐

热衷于技术写作 IT边角料

AIGC & Coding & Linux ...

~互撩~ TG: @Shaw_0xyz

页: [1]
查看完整版本: SpringBoot+AOP+注解+Redis防重复提交