java中通过自定义@preventduplicatesubmit注解结合aop切面与redis实现防重提交:请求携带一次性token,切面校验时执行del操作,成功则放行,失败则抛异常返回400。

Java 中通过自定义注解 + 拦截器(或 AOP)实现 API 接口的防重提交控制,核心思路是:在方法执行前校验请求是否重复(比如基于 token、时间戳、参数签名等),若重复则直接拦截并返回错误响应。
定义防重提交注解
创建一个运行时保留的自定义注解,用于标记需要防重的接口方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PreventDuplicateSubmit {
// 可配置过期时间(秒),默认 5 秒
long timeout() default 5;
// 是否严格校验参数(开启后相同参数 + 相同 token 才算重复)
boolean strict() default false;
}
生成与校验唯一提交凭证(如 Token)
通常由前端在表单加载时调用 /api/token 获取一次性 token,提交时携带该 token(如放在 Header 或 Body 中)。后端需:
- 提供生成 token 的接口,将 token 存入 Redis(带过期时间),值可为空或存时间戳
- 在防重逻辑中,先从请求中提取 token,再尝试
DEL该 key;若删除成功(返回 1),说明 token 有效且未被使用 → 允许提交;若删除失败(返回 0),说明已提交过或已过期 → 拒绝请求
结合拦截器或 AOP 实现统一校验
推荐使用 Spring AOP,在切面中处理注解逻辑:
- 使用
@Around切入带有@PreventDuplicateSubmit的方法 - 从
HttpServletRequest中获取 token(如request.getHeader("X-Submit-Token")) - 用 RedisTemplate 执行
redisTemplate.delete(token) - 若返回
false,抛出自定义异常(如DuplicateSubmitException),由全局异常处理器返回400 Bad Request和提示信息
注意事项与增强点
实际使用中需注意:
- token 必须一次性使用,且服务端校验后立即删除,不可仅查不删
- Redis 需保证高可用,避免因缓存故障导致误放行或误拦截
- 敏感操作建议叠加其他防护,如前端按钮置灰、时间窗口限制、用户+IP+接口维度限流
- 若用 JWT 或加密签名方式实现无状态 token,需校验签名+时间戳+随机数(nonce),防止重放
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











