背景
在实际开发过程中,防重复提交的操作很常见。有细分配置针对某一些路径进行拦截,也有基于注解去实现的指定方法拦截的。
分析
实现原理
实现防重复提交,我们很容易想到就是用过滤器或者拦截器来实现。
使用拦截器就是继承HandlerInterceptorAdapter
类,实现preHandle()
方法;
使用过滤器就是实现OncePerRequestFilter
接口,在doFilterInternal()
完成对应的防重复提交操作。
OncePerRequestFilter接口详解
在Spring Web应用程序中,过滤器(Filter)也是一种拦截HTTP请求和响应的机制,可以对它们进行处理或修改,从而增强或限制应用程序的功能。OncePerRequestFilter类是Spring提供的一个抽象类,继承自javax.servlet.Filter类,并实现了Spring自己的过滤器接口OncePerRequestFilter,它的目的是确保过滤器只会在每个请求中被执行一次,从而避免重复执行过滤器逻辑所带来的问题,如重复添加响应头信息等。
OncePerRequestFilter类中有一个doFilterInternal()方法,用于实现过滤器的逻辑,该方法只会在第一次请求时被调用,之后不再执行,确保了过滤器只会在每个请求中被执行一次。
实际场景考虑
使用过滤器的话,会对所有的请求都进行防重复提交。但对于一些查询接口来说,并不需要防重复提交。那么怎样在指定的接口需要使用防重复提交拦截呢?答案就是用注解。
实现步骤
1.定义注解@DuplicateSubmission
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 DuplicateSubmission {
}
2.DuplicateSubmissionFilter
实现防重复提交
方法一:基于过滤器与session
public class DuplicateSubmissionFilter extends OncePerRequestFilter {
private final Logger LOGGER = LoggerFactory.getLogger(DuplicateSubmissionFilter.class);
@Value(