SpringBoot拦截器实现项目防止接口重复提交

 更新时间:2023年09月03日 15:26:06   作者:草帽夫卡  
基于SpringBoot框架来开发业务后台项目时,接口重复提交是一个常见的问题,本文主要介绍了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 防止接口重复提交内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring 开发之组件赋值的实现方法

    Spring 开发之组件赋值的实现方法

    这篇文章主要介绍了Spring 开发之组件赋值的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 使用原生JDBC动态解析并获取表格列名和数据的方法

    使用原生JDBC动态解析并获取表格列名和数据的方法

    这篇文章主要介绍了使用原生JDBC动态解析并获取表格列名和数据,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Windows配置多版本JDK的详细步骤

    Windows配置多版本JDK的详细步骤

    JDK是Java开发工具包的缩写,包含了Java编译器、Java虚拟机、Java类库等众多组件,是Java开发的基石,提供了编写、编译和运行Java程序所必需的工具,有时候项目需要不同的JDK版本,所以本文给大家介绍了Windows配置多版本JDK的详细步骤,需要的朋友可以参考下
    2025-04-04
  • maven-maven使用-P参数打包不同环境问题

    maven-maven使用-P参数打包不同环境问题

    这篇文章主要介绍了maven-maven使用-P参数打包不同环境问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java如何通过ssh远程连接主机并执行命令

    Java如何通过ssh远程连接主机并执行命令

    这篇文章主要介绍了Java如何通过ssh远程连接主机并执行命令问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Springboot服务引用Nacos中新增的配置文件失败问题及解决

    Springboot服务引用Nacos中新增的配置文件失败问题及解决

    这篇文章主要介绍了Springboot服务引用Nacos中新增的配置文件失败问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • @Valid注解的作用及@Valid注解与@Validated的区别

    @Valid注解的作用及@Valid注解与@Validated的区别

    这篇文章主要介绍了@Valid注解的作用及@Valid注解与@Validated的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • java序列化与反序列化操作实例分析

    java序列化与反序列化操作实例分析

    这篇文章主要介绍了java序列化与反序列化操作,结合实例形式分析了java序列化与反序列化的概念与具体实现技巧,需要的朋友可以参考下
    2016-10-10
  • Hadoop源码分析六启动文件namenode原理详解

    Hadoop源码分析六启动文件namenode原理详解

    本篇是Hadoop源码分析系列文章第六篇,主要介绍Hadoop中的启动文件namenode,后续本系列文章会持续更新,有需要的朋友可以借鉴参考下
    2021-09-09
  • 微信APP支付(IOS手机端+java后台)版

    微信APP支付(IOS手机端+java后台)版

    这篇文章主要为大家详细介绍了微信APP支付(IOS手机端+java后台)版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05

最新评论