当前位置: 首页 > news >正文

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 {@Autowiredprivate 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)@ResponseBodypublic void test(){System.out.println("提交成功");}@RequestMapping("/a1")@ResponseBodypublic void test1(){System.out.println("提交成功1");}
}

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • dagger2实现原理
  • 网络安全威胁情报到底是什么
  • 存储实验:Linux挂载iscsi硬盘与华为OceanStor创建LUN全流程
  • SwiftUI 截图(snapshot)视频画面的极简方法
  • JavaScript 生成随机颜色
  • 《基于 LatentFactor + Redis + ES 实现动态药房分配方法》
  • HI3559AV100四路IMX334非融合拼接8K视频记录
  • Android中RecyclerView使用详解(一)
  • 每日复盘-20240715
  • CV06_Canny边缘检测算法和python实现
  • 内存函数(C语言)
  • 阿里新开源GPU版本的FunASR安装避坑
  • 乡镇集装箱生活污水处理设备处理效率高
  • Linux--USB驱动开发(二)插入USB后的内核执行程序
  • 安卓 APK 安装过程详解
  • 【css3】浏览器内核及其兼容性
  • css选择器
  • EventListener原理
  • fetch 从初识到应用
  • Git初体验
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 两列自适应布局方案整理
  • 前端面试之CSS3新特性
  • 前端之React实战:创建跨平台的项目架构
  • 我是如何设计 Upload 上传组件的
  • 一个完整Java Web项目背后的密码
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #每天一道面试题# 什么是MySQL的回表查询
  • (C语言)fgets与fputs函数详解
  • (Forward) Music Player: From UI Proposal to Code
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (二)学习JVM —— 垃圾回收机制
  • (翻译)terry crowley: 写给程序员
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (四)图像的%2线性拉伸
  • (原)本想说脏话,奈何已放下
  • (转)【Hibernate总结系列】使用举例
  • ... 是什么 ?... 有什么用处?
  • .aanva
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET NPOI导出Excel详解
  • .NET导入Excel数据
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • /var/spool/postfix/maildrop 下有大量文件
  • @Value读取properties中文乱码解决方案
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [15] 使用Opencv_CUDA 模块实现基本计算机视觉程序
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [ACP云计算]易混淆知识点(考题总结)
  • [Angular] 笔记 16:模板驱动表单 - 选择框与选项
  • [AR Foundation] 人脸检测的流程
  • [BZOJ2850]巧克力王国