Spring Boot 如何使用 AOP 防止重复提交

在 Spring Boot 中,可以使用 AOP(面向切面编程)来防止重复提交。通过 AOP,可以在方法调用前后添加额外的逻辑,而不需要修改方法本身的代码。下面是一个基于 AOP 的解决方案:

使用 AOP 防止重复提交

步骤:

  1. 定义注解:创建一个自定义注解,用于标记需要防止重复提交的方法。
  2. 编写切面:使用 AOP 切面,在方法调用前检查重复提交的条件。

1. 定义注解

首先,创建一个自定义注解 @NoRepeatSubmit

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. 编写切面

然后,编写一个 AOP 切面类,在方法调用前检查请求是否重复提交。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;@Aspect
@Component
public class NoRepeatSubmitAspect {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Around("@annotation(noRepeatSubmit)")public Object around(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();// 这里也可以从请求头里取Token,和前端商量好就行。String sessionId = request.getSession().getId();String uri = request.getRequestURI();String key = "no_repeat_submit:" + sessionId + ":" + uri;// 这里可以改为用一个分布式锁工具Boolean isAbsent = stringRedisTemplate.opsForValue().setIfAbsent(key, "locked", 5, TimeUnit.SECONDS);if (Boolean.TRUE.equals(isAbsent)) {try {return joinPoint.proceed();} finally {stringRedisTemplate.delete(key);}} else {throw new RuntimeException("重复提交");}}
}

3. 应用注解

在需要防止重复提交的方法上使用 @NoRepeatSubmit 注解。

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api")
public class FormController {@NoRepeatSubmit@PostMapping("/submitForm")public String submitForm() {// 处理表单提交逻辑return "success";}
}

说明

  1. 注解 @NoRepeatSubmit:用于标记需要防止重复提交的方法。
  2. 切面 NoRepeatSubmitAspect:通过 Redis 锁机制来防止重复提交。在方法调用前,生成一个基于 session ID 和请求 URI 的唯一键,尝试获取 Redis 锁,如果获取成功则继续执行方法并在执行完成后释放锁;如果获取失败,则抛出重复提交异常。

注意事项

  1. Redis 配置:确保应用程序中已经配置了 Redis。
  2. 异常处理:可以通过全局异常处理器来捕获和处理重复提交异常。

这种方式适用于单节点和分布式部署的场景,因为 Redis 可以作为一个全局的锁服务,保证分布式环境下的唯一性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker-compose Install homer

homer前言 一个非常简单的静态主页,为您的服务器保持您的服务在手,从一个简单的yaml配置文件。 前提要求 安装 docker docker-compose 参考创建一键安装homer 脚本 homer安装位置/homerhomer 脚本位置/homer/assetshomer logo 图标/home/assets/iconshomer 端口80homer 颜色…

运维 之 大文件分片刻录光盘

需求 因有些企业中涉及设备只能通过光盘介质方式拷贝文件,然而采购的单张光盘又不能确保存放下一些较大的文件,所以只能通过分片的方式逐个光盘存储。 Windows处理 1、安装压缩软件(自行选择,这里使用WinRAR)、Ultr…

vue项目input框使用lodash的debounce防抖

1、安装lodash工具 npm install lodash2、引入 import _ from lodash3、使用debounce处理防抖 // template <el-input placeholder"请输入名称" v-model"key" input"handleInput"> </el-input>methods:{handleInput: _.debounce…

HTML静态网页成品作业(HTML+CSS)——企业酒店官网网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

FuTalk设计周刊-Vol.053

#AI漫谈 热点捕手 1.Midjourney推出新功能Room 用户可在聊天室中一起创作图像 Midjourney最近推出了一个有趣的新功能——Room&#xff0c;为用户提供了一个协作和社交平台&#xff0c;用户可以一起创建和分享图像&#xff0c;并参与实时聊天。Room促进了用户之间的互动和合作…

C语言 | Leetcode C语言题解之第111题二叉树的最小深度

题目&#xff1a; 题解&#xff1a; typedef struct {int val;struct TreeNode *node;struct queNode *next; } queNode;void init(queNode **p, int val, struct TreeNode *node) {(*p) (queNode *)malloc(sizeof(queNode));(*p)->val val;(*p)->node node;(*p)->…

CentOS 7安装alertmanager

说明&#xff1a;本文介绍如何在CentOS 7安装alertmanager&#xff1b; Step1&#xff1a;下载安装包 访问Github仓库&#xff0c;下载对应版本的alertmanager安装包 https://github.com/prometheus/alertmanager/releases 如何查看自己系统的信息&#xff0c;可参考下图中的…

AI播客下载:The Logan Bartlett Show Podcast(AI创业投资主题)

Logan Bartlett Show Podcast是一个播客&#xff0c;主持人Logan Bartlett与科技界的领导者以及投资者进行对话&#xff0c;讨论他们在运营或投资企业中学到的经验教训&#xff0c;主要集中在科技创投领域。 Logan Bartlett 是 Redpoint Ventures 的投资人&#xff0c;并且在该…

LVGL里tileview的使用与隐藏滚动条

使用环境&#xff1a; LVGLV8.3 vs2019模拟器。与freertos集成。去我上传的资源里找。 解决方法&#xff1a; /** 需要实现的功能&#xff1a; 使用tileview控件&#xff0c;并创建两个tile&#xff0c;左右排列。通过左右滑动&#xff0c;可以相互切换。 **/ /************…

【DZ模板】克米设计APP手机版本地化+完美使用

模版介绍 【DZ模板】价值288克米设计APP手机版DZ模板 数据本地化完美使用 腾讯官方出品discuz论坛DIY的后台设置&#xff0c;功能齐全&#xff0c;论坛功能不亚于葫芦侠&#xff0c;自定义马甲&#xff0c;自定义认证&#xff0c;自定义广告&#xff0c;完全可以打造出自己想…

SW 弯曲找方向

当旋转弯曲轴的时候,半径和角度 越和理论的接近,越接近(只要输入角度,然后旋转弯曲轴,看半径跟随的变化值)

hetaozy-2D/2D数列位置问题

【任务描述】一个数列&#xff0c;删掉若干个数后&#xff0c;正好有一些数的数值等于自己所在的位置的编号&#xff0c;比如数列1 1 2 5 4删掉一个1后的数位为&#xff1a;1 2 5 4&#xff0c;其中1在1号位置&#xff0c;2在2号位置&#xff0c;4在4号位置。 现给定n个数的数列…

Java-SpringBoot集成Langchain4j文本嵌入模型实现向量相似度查询

集成Pg数据库并创建vector字段类型 运行pgvector容器 根据需要进行容器目录挂载 docker run --name pgvector \-e POSTGRES_PASSWORD123456 \-p 5432:5432 \-d --platform linux/amd64 ankane/pgvector:latest 进入docker容器并创建vector字段类型 docker exec -it pgvecto…

2024Spring> HNU-计算机系统-实验4-Buflab-导引+验收

前言 称不上导引了&#xff0c;因为验收已经结束了。主要是最近比较忙&#xff0c;在准备期末考试。周五晚上才开始看实验&#xff0c;自己跟着做了一遍实验&#xff0c;感觉难度还是比bomblab要低的&#xff0c;但是如果用心做的话对于栈帧的理解确实能上几个档次。 实验参考…

基于antd的DatePicker 组件封装业务组件

先看一下我写的目录结构: 依次来看业务代码; (1)RangeTime.tsx import {useState,uesCallback} from react; import {DatePicker} from antd; import {RangePickerProps as AntdRangePickerProps} from antd/es/date-picker; import {Moment} from moment; import type {Ran…

ROCm上来自Transformers的双向编码器表示(BERT)

14.8. 来自Transformers的双向编码器表示&#xff08;BERT&#xff09; — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import torch from torch import nn from d2l import torch as d2l#save def get_tokens_and_segments(tokens_a, tokens_bNone):""&qu…

驾校管理系统-手把手调试搭建

驾校管理系统-手把手调试搭建 驾校管理系统-手把手调试搭建

rk3568_atomic

文章目录 前言一、atomic是什么?二、原子操作API函数1.atomic原子操作2.原子位操作API三、atomic驱动实验总结前言 本文记录的是正点原子rk3568开发板的atomic实验 一、atomic是什么? 不同的线程在进行读写的过程中,可能会冲突乱入,导致会有预想不到的结果。所以为了让数…

开源模型应用落地-LangSmith试炼-入门初体验-数据集评估(三)

一、前言 LangSmith是一个用于构建生产级 LLM 应用程序的平台&#xff0c;它提供了调试、测试、评估和监控基于任何 LLM 框架构建的链和智能代理的功能&#xff0c;并能与LangChain无缝集成。通过使用LangSmith帮助开发者深入了解模型在不同场景下的表现&#xff0c;让开发者能…

python使用xlrd读取excel的时候把字符串读成了数字

xlrd 是一个 Python 库&#xff0c;用于读取 Excel 文件&#xff08;.xls 和 .xlsx&#xff0c;但 .xlsx 需要 openpyxl 或 xlrd 的较新版本&#xff09;。然而&#xff0c;xlrd 在读取 Excel 文件时通常会将单元格的内容按其原始数据类型&#xff08;如字符串、数字、日期等&a…