返回

别再纠结重复提交问题!试试使用自定义注解的解决方案

后端

使用自定义注解巧妙解决重复提交难题

在现代网络应用中,表单提交、支付交易等场景下,重复提交是一个恼人的问题。当用户不小心重复提交同一个表单或多次支付时,后端需要采取措施防止重复操作,以避免数据不一致或安全风险。

传统解决方案的局限性

传统上,防止重复提交的方法主要有锁、唯一约束、乐观锁等。这些方法虽然能有效防止重复提交,但各有弊端:

  • 锁: 需要在数据库层加锁,影响性能。
  • 唯一约束: 需修改数据库表结构,增加复杂性。
  • 乐观锁: 需要在代码中进行版本控制,增加代码复杂度和出错风险。

自定义注解的优雅方案

针对传统解决方案的不足,我们可以使用自定义注解 来实现防止重复提交。这种方法更加简单、灵活,兼容性强。

实现步骤:

  1. 创建自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface PreventDuplicateSubmission {

    // 防重复提交有效期(秒)
    int expireTime() default 60;
}
  1. 在需要防止重复提交的方法上添加注解:
@PostMapping("/submitForm")
@PreventDuplicateSubmission(expireTime = 30)
public void submitForm(@RequestBody FormDTO formDTO) {
    // 业务逻辑
}
  1. 后端框架中实现注解逻辑:

以 Spring Boot 为例,可在拦截器中实现注解逻辑:

public class PreventDuplicateSubmissionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        Method method = ((HandlerMethod) handler).getMethod();
        PreventDuplicateSubmission annotation = method.getAnnotation(PreventDuplicateSubmission.class);
        if (annotation != null) {
            String token = request.getHeader("X-Token");
            // 检查 token 是否有效
            if (token == null || !isValidToken(token)) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                return false;
            }
            // 检查是否在有效期内
            long currentTimeMillis = System.currentTimeMillis();
            long tokenCreateTime = Long.parseLong(token.split(":")[0]);
            if (currentTimeMillis - tokenCreateTime > annotation.expireTime() * 1000) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                return false;
            }
        }
        return true;
    }

    // 根据 token 验证逻辑
    private boolean isValidToken(String token) {
        // ...
    }
}

自定义注解的优势:

  • 简洁易用: 只需在方法上添加注解,无需修改数据库或代码。
  • 灵活可配: 可配置有效期等参数,适应不同场景。
  • 兼容性强: 兼容任何后端框架或技术栈。

总结:

使用自定义注解防止重复提交是一种简单、灵活、兼容性强的解决方案。它有效地解决了重复提交问题,同时兼顾性能和代码简洁性。

常见问题解答:

  1. 如何生成 token?

    • 可以使用 UUID、时间戳或其他安全随机机制生成 token。
  2. 如何存储 token?

    • 可以将其存储在数据库、缓存或 cookie 中,根据具体场景选择。
  3. 有效期太短会怎样?

    • 有效期过短可能导致合法提交被阻止,需要根据实际情况设置合理的有效期。
  4. 有效期太长会有安全隐患吗?

    • 有效期过长可能为攻击者提供窗口期,建议将有效期限制在合理范围内。
  5. 如果用户频繁提交,会不会被误判为重复提交?

    • 使用有效的 token 验证机制和适当的有效期,可以有效避免误判。