SpringBoot防抖方案(防止表单重复提交)
在Spring Boot中,可以使用AOP(面向切面编程)来实现防抖操作,以防止表单的重复提交。以下是一个简单的实现示例:
首先,创建一个注解来标记需要防抖的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatSubmit {
// 可以添加一些配置属性,如超时时间等
}
然后,创建一个AOP切面来处理防抖逻辑:
@Aspect
@Component
public class RepeatSubmitAspect {
// 配置一个超时时间,例如30秒内不允许重复提交
private static final int TIMEOUT = 30;
// 定义一个缓存,用于存储用户的提交记录
private final Cache<String, Object> cache = Caffeine.newBuilder()
.expireAfterWrite(TIMEOUT, TimeUnit.SECONDS)
.build();
@Around("@annotation(com.yourpackage.RepeatSubmit)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 获取方法上的注解
RepeatSubmit repeatSubmit = method.getAnnotation(RepeatSubmit.class);
if (repeatSubmit == null) {
return joinPoint.proceed();
}
// 获取请求中的用户标识和请求参数等信息,用于确定是否为同一用户的重复提交
// 这里假设用户标识存在于HTTP请求头中的"User-Id"字段
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
String userId = attributes.getRequest().getHeader("User-Id");
String key = userId + "_" + method.getName();
// 检查缓存中是否存在该键,如果存在,则认为是重复提交
if (cache.getIfPresent(key) != null) {
// 这里可以返回一个错误信息或者抛出异常
throw new RuntimeException("重复提交,请稍后再试。");
} else {
// 如果不是重复提交,将键存入缓存中
cache.put(key, new Object());
}
}
// 如果不是重复提交,执行原方法逻辑
return joinPoint.proceed();
}
}
最后,在需要防抖的Controller方法上使用@RepeatSubmit
注解:
@RestController
public class YourController {
@RepeatSubmit
@PostMapping("/submit")
public String submitForm(YourForm form) {
// 处理提交逻辑
return "提交成功";
}
}
这样就通过AOP的方式实现了防抖操作,防止用户在短时间内对同一个接口进行重复提交。
评论已关闭