SpringBoot攔截器實(shí)現(xiàn)項(xiàng)目防止接口重復(fù)提交
基于SpringBoot框架來開發(fā)業(yè)務(wù)后臺項(xiàng)目時,接口重復(fù)提交是一個常見的問題。為了避免這個問題,我們可以通過自定義攔截器實(shí)現(xiàn)一個后臺攔截接口重復(fù)提交的功能,本文將介紹如何使用基于SpringBoot實(shí)現(xiàn)這個功能。
- 首先,我們需要引入一個Aop依賴。在pom.xml文件中添加如下依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 創(chuàng)建一個自定義注解
@NoRepeatSubmit
,用于標(biāo)記需要攔截的接口:
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 { /** * 設(shè)置請求鎖定時間,默認(rèn)為5秒 */ int lockTime() default 5; }
- 創(chuàng)建一個攔截器類
NoRepeatSubmitInterceptor
,實(shí)現(xiàn)HandlerInterceptor
接口,并在其中實(shí)現(xiàn)攔截邏輯:
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; 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 javax.servlet.http.HttpSession; import java.util.UUID; import java.util.concurrent.TimeUnit; @Aspect @Component public class NoRepeatSubmitInterceptor implements HandlerInterceptor { @Pointcut("@annotation(com.example.demo.annotation.NoRepeatSubmit)") public void noRepeatSubmitPointcut() { } @Around("noRepeatSubmitPointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 獲取請求參數(shù)中的token值 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession session = request.getSession(); String token = session.getAttribute("token").toString(); // 判斷是否已經(jīng)提交過請求,如果已經(jīng)提交過并且時間間隔小于鎖時間,則直接返回成功結(jié)果,否則認(rèn)為是重復(fù)提交,拋出異常并鎖定session if (isSubmitted(token)) { String lockKey = UUID.randomUUID().toString(); session.setAttribute(lockKey, System.currentTimeMillis()); throw new RuntimeException("請勿重復(fù)提交"); } else { session.setAttribute("token", token); return joinPoint.proceed(); } } private boolean isSubmitted(String token) { HttpSession session = request.getSession(); Object lockKey = session.getAttribute(token); if (lockKey == null) { return false; } else { long lockTime = (Long) session.getAttribute(token); if (lockTime > 0 && System.currentTimeMillis() - lockTime < TimeUnit.SECONDS.toMillis(5)) { return true; } else { session.removeAttribute(token); return false; } } } }
- 注冊攔截器
實(shí)現(xiàn)HandlerInterceptor接口的重寫,重寫preHandle、postHandle、afterCompletion方法。攔截器中的方法執(zhí)行流程為 preHandle → controlle → postHandle → afterCompletion。然后需要將攔截器注冊到容器中,可以通過實(shí)現(xiàn)WebMvcConfigurer的addInterceptors方法來實(shí)現(xiàn)。下面是一個簡單的例子:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new NoRepeatSubmitInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/register"); } }
- 在需要進(jìn)行攔截的接口上添加
@NoRepeatSubmit
注解,例如:
@RestController public class UserController { @NoRepeatSubmit // 添加此注解表示該接口需要攔截重復(fù)提交請求 @GetMapping("/submit") public String submit() { // 處理業(yè)務(wù)邏輯... return "success"; } }
通過以上步驟,我們實(shí)現(xiàn)了一個簡單的后臺攔截接口重復(fù)提交的功能。在實(shí)際項(xiàng)目中,還需要考慮更多的細(xì)節(jié),例如如何保證鎖的釋放、如何處理并發(fā)請求等。但這個示例應(yīng)該能幫助你入門SpringBoot攔截器的使用。
到此這篇關(guān)于SpringBoot攔截器實(shí)現(xiàn)項(xiàng)目防止接口重復(fù)提交的文章就介紹到這了,更多相關(guān)SpringBoot 防止接口重復(fù)提交內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot 防止重復(fù)請求防止重復(fù)點(diǎn)擊的操作
- SpringBoot?使用AOP?+?Redis?防止表單重復(fù)提交的方法
- SpringBoot+Redis使用AOP防止重復(fù)提交的實(shí)現(xiàn)
- SpringBoot整合redis+Aop防止重復(fù)提交的實(shí)現(xiàn)
- SpringBoot中防止接口重復(fù)提交的有效方法
- SpringBoot利用Redis實(shí)現(xiàn)防止訂單重復(fù)提交的解決方案
- SpringBoot整合ShedLock解決定時任務(wù)防止重復(fù)執(zhí)行的問題
- springboot基于注解實(shí)現(xiàn)去重表消息防止重復(fù)消費(fèi)
相關(guān)文章
springboot整合Mybatis、JPA、Redis的示例代碼
這篇文章主要介紹了springboot整合Mybatis、JPA、Redis的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Java對Map進(jìn)行按value排序的幾種常見方法
在日常開發(fā)中,Map 是我們經(jīng)常使用的數(shù)據(jù)結(jié)構(gòu)之一,盡管 Map 是按鍵 (key) 存儲和檢索數(shù)據(jù)的,但有時我們需要根據(jù) value 進(jìn)行排序,這篇博客將詳細(xì)探討如何在 Java 中對 Map 進(jìn)行按 value 排序的幾種常見方法,并分析它們的優(yōu)缺點(diǎn),需要的朋友可以參考下2025-03-03Spring Boot教程之利用ActiveMQ實(shí)現(xiàn)延遲消息
這篇文章主要給大家介紹了關(guān)于Spring Boot教程之利用ActiveMQ實(shí)現(xiàn)延遲消息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11idea使用mybatis插件mapper中的方法爆紅的解決方案
這篇文章主要介紹了idea使用mybatis插件mapper中的方法爆紅的解決方案,文中給出了詳細(xì)的原因分析和解決方案,對大家解決問題有一定的幫助,需要的朋友可以參考下2024-07-07Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例
這篇文章主要介紹了Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11