java如何防止表单重复提交
使用Token机制防止重复提交
在表单页面生成一个随机Token(如UUID),存储在Session或Redis中。提交表单时携带该Token,服务器验证后立即清除Token。若重复提交,Token已失效导致验证失败。
// 生成Token示例
String token = UUID.randomUUID().toString();
request.getSession().setAttribute("formToken", token);
// 验证Token示例
String sessionToken = (String) request.getSession().getAttribute("formToken");
if (sessionToken == null || !sessionToken.equals(request.getParameter("token"))) {
return "error:重复提交";
}
前端按钮禁用技术
通过JavaScript在表单提交后立即禁用提交按钮,防止用户多次点击。可结合CSS设置禁用状态样式提升用户体验。
document.getElementById("submitBtn").addEventListener("click", function() {
this.disabled = true;
this.form.submit();
});
重定向模式(Post/Redirect/Get)
处理POST请求后返回302重定向至结果页面。浏览器刷新时只会重复GET请求,避免重复提交表单数据。Spring MVC中可通过redirect:前缀实现。
@PostMapping("/submit")
public String handleSubmit(Form form) {
// 处理表单数据
return "redirect:/success";
}
请求限流控制
对相同IP或用户ID的请求进行限流,例如使用Guava RateLimiter或Redis实现计数器。设置合理时间窗口(如5秒内只允许1次提交)。
// Guava限流示例
RateLimiter limiter = RateLimiter.create(1.0); // 每秒1次
if (!limiter.tryAcquire()) {
throw new RuntimeException("操作过于频繁");
}
数据库唯一约束
对业务关键字段添加数据库唯一索引。如订单号字段设置UNIQUE约束,重复提交时会触发异常,可通过事务回滚处理。
ALTER TABLE orders ADD UNIQUE (order_no);
幂等性设计
为每个请求分配唯一ID(如雪花ID),服务端记录已处理ID。重复ID直接返回之前的结果。适用于支付等关键业务场景。

// 幂等检查伪代码
if (redis.exists(requestId)) {
return redis.get(requestId);
} else {
// 处理业务
redis.setex(requestId, 3600, result);
}






