【SpringBoot】SpringBoot中防止接口重复提交(单机环境和分布式环境)
在Spring Boot应用中防止接口重复提交,可以通过以下几种方式实现:
- 使用Token机制:为每个表单生成一个唯一的token,将token存储在session或者数据库中,并将token添加到表单的隐藏字段。当用户提交表单时,检查token是否存在且与session中的一致,如果一致则处理请求并清除token,否则拒绝请求。
- 使用锁机制:如果是单机环境,可以使用Java并发工具类如
ReentrantLock
来锁定特定的资源,防止重复提交。 - 使用分布式锁:如果是分布式环境,可以使用Redis等中间件提供的分布式锁特性,在处理请求时获取锁,处理完毕后释放锁,其他实例在尝试获取锁时将被阻塞直到锁被释放。
以下是使用Token机制的一个简单示例:
@Controller
public class MyController {
@Autowired
private HttpSession session;
@GetMapping("/form")
public String getForm(Model model) {
String token = UUID.randomUUID().toString();
session.setAttribute("formToken", token);
model.addAttribute("token", token);
return "form";
}
@PostMapping("/submit")
public String submitForm(@RequestParam("token") String token, @ModelAttribute MyForm form) {
String sessionToken = (String) session.getAttribute("formToken");
if (token != null && token.equals(sessionToken)) {
// 处理请求
// ...
// 清除session中的token
session.removeAttribute("formToken");
return "success";
} else {
return "duplicate";
}
}
}
在HTML表单中,隐藏字段如下所示:
<form action="/submit" method="post">
<input type="hidden" name="token" value="${token}"/>
<!-- 其他表单字段 -->
<input type="submit" value="Submit"/>
</form>
以上代码中,我们在获取表单时生成一个唯一的token,并将其存储在session中,同时将token传递给前端的表单。当用户提交表单时,我们检查token是否与session中的一致,从而避免了重复提交。
评论已关闭