SpringBoot拦截器实现项目防止接口重复提交
基于SpringBoot框架来开发业务后台项目时,接口重复提交是一个常见的问题。为了避免这个问题,我们可以通过自定义拦截器实现一个后台拦截接口重复提交的功能,本文将介绍如何使用基于SpringBoot实现这个功能。
- 首先,我们需要引入一个Aop依赖。在pom.xml文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>- 创建一个自定义注解
@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 {
/**
* 设置请求锁定时间,默认为5秒
*/
int lockTime() default 5;
}- 创建一个拦截器类
NoRepeatSubmitInterceptor,实现HandlerInterceptor接口,并在其中实现拦截逻辑:
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 {
// 获取请求参数中的token值
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
String token = session.getAttribute("token").toString();
// 判断是否已经提交过请求,如果已经提交过并且时间间隔小于锁时间,则直接返回成功结果,否则认为是重复提交,抛出异常并锁定session
if (isSubmitted(token)) {
String lockKey = UUID.randomUUID().toString();
session.setAttribute(lockKey, System.currentTimeMillis());
throw new RuntimeException("请勿重复提交");
} 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;
}
}
}
}- 注册拦截器
实现HandlerInterceptor接口的重写,重写preHandle、postHandle、afterCompletion方法。拦截器中的方法执行流程为 preHandle → controlle → postHandle → afterCompletion。然后需要将拦截器注册到容器中,可以通过实现WebMvcConfigurer的addInterceptors方法来实现。下面是一个简单的例子:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new NoRepeatSubmitInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/register");
}
}- 在需要进行拦截的接口上添加
@NoRepeatSubmit注解,例如:
@RestController
public class UserController {
@NoRepeatSubmit // 添加此注解表示该接口需要拦截重复提交请求
@GetMapping("/submit")
public String submit() {
// 处理业务逻辑...
return "success";
}
}通过以上步骤,我们实现了一个简单的后台拦截接口重复提交的功能。在实际项目中,还需要考虑更多的细节,例如如何保证锁的释放、如何处理并发请求等。但这个示例应该能帮助你入门SpringBoot拦截器的使用。
到此这篇关于SpringBoot拦截器实现项目防止接口重复提交的文章就介绍到这了,更多相关SpringBoot 防止接口重复提交内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
springboot整合Mybatis、JPA、Redis的示例代码
这篇文章主要介绍了springboot整合Mybatis、JPA、Redis的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-09-09
Spring Boot教程之利用ActiveMQ实现延迟消息
这篇文章主要给大家介绍了关于Spring Boot教程之利用ActiveMQ实现延迟消息的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧2019-11-11
idea使用mybatis插件mapper中的方法爆红的解决方案
这篇文章主要介绍了idea使用mybatis插件mapper中的方法爆红的解决方案,文中给出了详细的原因分析和解决方案,对大家解决问题有一定的帮助,需要的朋友可以参考下2024-07-07
Mybatis 动态sql if 判读条件等于一个数字的案例
这篇文章主要介绍了Mybatis 动态sql if 判读条件等于一个数字的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-11-11


最新评论