Spring项目中页面刷新时如何防止数据重复提交?PRG模式解决方案求助
解决Spring MVC刷新结果页数据重复问题(PRG模式实践)
你遇到的这个问题是Web开发里非常典型的POST重复提交场景——当你在结果页刷新时,浏览器会重新发送之前的POST请求,导致service.create(formData)被再次执行,数据自然就重复了。咱们用**PRG模式(Post/Redirect/Get)**就能完美解决这个问题,我给你拆解下怎么改代码:
问题根源分析
你当前的processForm方法在表单验证通过后,直接用mv.setViewName("result")做了服务器端转发(forward),这时候浏览器地址栏仍然是/send-form-data这个POST请求的地址。刷新页面时,浏览器会重新发送一次POST请求,重复执行数据插入逻辑,最终导致数据重复。
PRG模式解决方案
PRG的核心思路是:处理完POST提交后,不要直接返回结果视图,而是重定向到一个GET请求的结果页面。这样浏览器地址栏会变成GET请求的地址,后续刷新只会发送GET请求(仅做数据查询,不会执行插入操作),从根本上避免重复提交。
修改步骤及代码示例
改造POST请求处理方法
将原来直接返回result视图的逻辑,改成重定向到一个新的GET请求接口,同时可以用RedirectAttributes传递临时数据(比如提交成功的表单数据,可选):@RequestMapping(value = "/send-form-data", method = RequestMethod.POST) public String processForm(@Valid @ModelAttribute("formData") SampleModel formData, BindingResult res, RedirectAttributes redirectAttributes) { fmv.validate(formData, res); if(res.hasErrors()) { // 验证失败,返回表单页面(这里用forward没问题,刷新只是重新加载表单) return "mainPage"; } else { // 执行数据插入操作(只执行一次) service.create(formData); // 可选:用FlashAttribute传递临时数据,重定向后能在GET方法中获取 redirectAttributes.addFlashAttribute("submittedData", formData); // 重定向到结果页的GET请求 return "redirect:/show-results"; } }新增结果页的GET请求处理方法
专门写一个GET接口来负责查询数据并返回结果视图,这样刷新页面时只会执行数据查询逻辑:@RequestMapping(value = "/show-results", method = RequestMethod.GET) public ModelAndView showResults() { ModelAndView mv = new ModelAndView("result"); // 查询最新的数据列表 mv.addObject("list", service.findAll()); // 如果需要使用之前传递的表单数据,可从FlashAttribute中获取 // SampleModel submittedData = (SampleModel) mv.getModel().get("submittedData"); return mv; }
为什么这样改就有效?
- 当表单提交成功后,服务器返回重定向响应,浏览器会自动发送一个GET请求到
/show-results,地址栏也会更新为这个GET地址。 - 后续刷新页面时,浏览器只会重新发送这个GET请求,而GET请求的逻辑只是查询数据,不会执行
service.create(formData)插入操作,自然就不会出现数据重复的问题了。
内容的提问来源于stack exchange,提问作者can




