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 防止接口重复提交内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot整合Mybatis、JPA、Redis的示例代码

    springboot整合Mybatis、JPA、Redis的示例代码

    这篇文章主要介绍了springboot整合Mybatis、JPA、Redis的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java对Map进行按value排序的几种常见方法

    Java对Map进行按value排序的几种常见方法

    在日常开发中,Map 是我们经常使用的数据结构之一,尽管 Map 是按键 (key) 存储和检索数据的,但有时我们需要根据 value 进行排序,这篇博客将详细探讨如何在 Java 中对 Map 进行按 value 排序的几种常见方法,并分析它们的优缺点,需要的朋友可以参考下
    2025-03-03
  • Spring Boot教程之利用ActiveMQ实现延迟消息

    Spring Boot教程之利用ActiveMQ实现延迟消息

    这篇文章主要给大家介绍了关于Spring Boot教程之利用ActiveMQ实现延迟消息的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11
  • idea使用mybatis插件mapper中的方法爆红的解决方案

    idea使用mybatis插件mapper中的方法爆红的解决方案

    这篇文章主要介绍了idea使用mybatis插件mapper中的方法爆红的解决方案,文中给出了详细的原因分析和解决方案,对大家解决问题有一定的帮助,需要的朋友可以参考下
    2024-07-07
  • SpringBoot配置和切换Tomcat流程详解

    SpringBoot配置和切换Tomcat流程详解

    这篇文章主要介绍了如何给springboot配置和切换默认的Tomcat容器以及相关的经验技巧,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • java代理 jdk动态代理应用案列

    java代理 jdk动态代理应用案列

    java代理有jdk动态代理、cglib代理,这里只说下jdk动态代理,jdk动态代理主要使用的是java反射机制,需要了解的朋友可以参考下
    2012-11-11
  • SpringBoot整合jasypt加密配置文件敏感信息

    SpringBoot整合jasypt加密配置文件敏感信息

    在项目中我们需要对配置文件的一些敏感信息进行加密处理,比如数据库账户密码,避免直接暴露出来,这种场景常常用于生产环境,我们不想让开发人员知道生产库的密码,有运维人员统一管理,所以本文给大家介绍了SpringBoot整合jasypt加密配置文件敏感信息
    2024-06-06
  • Java 抽象类特点总结

    Java 抽象类特点总结

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
    2021-10-10
  • 深入理解Java8双冒号::的使用

    深入理解Java8双冒号::的使用

    这篇文章主要介绍了深入理解Java8双冒号::的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Mybatis 动态sql if 判读条件等于一个数字的案例

    Mybatis 动态sql if 判读条件等于一个数字的案例

    这篇文章主要介绍了Mybatis 动态sql if 判读条件等于一个数字的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11

最新评论