自学内容网 自学内容网

SpringBoot防止重复提交 AOP+自定义注解+redis

1.什么是重复提交呢

  在Web开发中,重复提交(也称为双重提交或重复表单提交)是指用户在没有明确意图的情况下,多次提交同一表单的情况。这可能是由于用户多次点击提交按钮、表单提交过程中的网络延迟导致用户重复点击、或者由于浏览器的自动重试机制(如在网络中断后恢复连接时)等原因造成的。

  这种情况可能造成数据库插入多条数据等等

2.用一个小例子实现防止重复提交

2.1 首先自定义一个注解,用来给方法设置多长时间内再次调用相同的数据,属于重复提交

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExpirationTime {
    // 可以定义一些属性,比如超时时间等
    long timeout() default 60; // 默认60秒
}

2.2 通过AOP在执行方法前做检查,存入到redis中,通过给redis中设置过期时间,实现防止重复提交功能

@Component
@Aspect
public class RepeatSubmitAspect {
    @Autowired
    private RedisTemplate redisTemplate;
    @Pointcut("@annotation(com.qcby.submitageain.annotationaop.ExpirationTime)")
    public void repeatSubmit() {

    }
    @Around("repeatSubmit()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
          .getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        StringBuffer requestURL = request.getRequestURL();
        // 如果需要包括查询字符串,可以添加
        String queryString = request.getQueryString();
        if (queryString != null) {
            requestURL.append("?").append(queryString);
        }
        String requestURL1 = requestURL.toString();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        // 获取防重复提交注解
        ExpirationTime annotation = method.getAnnotation(ExpirationTime.class);
        //设置初始值为0,表示如果该没有这个注解,就设置过期时间为0,也就是不存入redis中
        long timeout=0;
        if(annotation!=null){
            timeout = annotation.timeout();
        }
        if (!redisTemplate.hasKey(requestURL1)||this.redisTemplate.opsForValue().get(requestURL1)==null) {
            this.redisTemplate.opsForValue().set(requestURL1, true, timeout, TimeUnit.SECONDS);
            try {
                //正常执行方法并返回
                return joinPoint.proceed();
            } catch (Throwable throwable) {
                throw new Throwable(throwable);
            }
        } else {
            // 抛出异常
            System.out.println("请勿重复提交");
            return null;
        }
    }
}

2.3 此时就可以编写controller层来测试代码是否成功啦~

@Controller
public class TestController {
    @RequestMapping("/a2")
    @ExpirationTime(timeout = 5)
    @ResponseBody
    public void test(){
        System.out.println("提交成功");
    }
    @RequestMapping("/a1")
    @ResponseBody
    public void test1(){
        System.out.println("提交成功1");
    }
}

2.4 此刻一个简单的防止重复提交的一个小程序就完成啦~


原文地址:https://blog.csdn.net/m0_57921272/article/details/140333165

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!