我正在使用 thymeleaf 和 Spring MVC 进行 Post/Redirect/Get 操作,效果很好。除了当我到达页面执行 GET 并进行刷新时,ModelAttribute 会被重置。这是我正在做的类似事情的片段。
@RequestMapping("/site")
public class SiteController {
@RequestMapping(values = {"", "/"}, method = RequestMethod.GET)
public String index(@ModelAttribute("form") Form form, Model model) {
return "/site/index";
}
@RequestMapping(values = {"/postit"}, method = RequestMethod.POST)
public String indexPoster(@ModelAttribute("form") Form form, Model model, RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("form", form);
return "redirect:/site/result";
}
@RequestMapping(values = {"/result"}, method = RequestMethod.GET)
public String indexResult(@ModelAttribute("form") Form form, Model model) {
// This will print the form, but if I do a page reload, the form properties will be reset.
System.out.println(form);
return "/site/result";
}
}
我的Form
对象只是一个简单的java bean,有一个名为name
的字符串属性,显然我的真实表单有一堆属性,但这是为了简单起见问题。
在/site/index 的 html 页面上,我有一个使用 th:object="${form}"
和 th:field="*{name}"< 的简单表单
向 /postit
发送帖子。在我的/site/result 上,我只输出在表单中输入的名称。 (所以现在这有点像 Hello World :) )。
此流程适合我,但如果我在加载/site/result 后点击刷新,indexResult
中的表单变量将被重置。
我尝试过使用
private Form form;
@ModelAttribute("form")
public Form getForm() {
if (this.form == null) {
this.form = new Form();
}
return this.form;
}
在类(class)层面上,但感觉“hacky”。如果我离开该页面,执行其他操作,然后返回旧数据仍将在那里。
在这个项目中,我们(尽可能)避免使用 session 来存储数据。
最佳答案
您遇到的是 Flash 属性的确切行为。它们在重定向之前存储在 session 中,然后在重定向之后作为模型属性加载并立即从 session 中删除。它们仅在重定向后出现在单个请求中。
不幸的是,似乎没有一种非常优雅的方法来处理对需要某些闪存/模型属性的请求映射的请求。一种方法是添加具有预定义键/值的 flash 属性。这将在重定向后作为模型属性出现。如果缺少,您可以采取相应措施(例如重定向到初始表单)。
如果您希望表单数据在多次刷新结果页面后可用,您必须使用 session 或通过 URL 将它们作为请求属性发送,尽管后者并不是真正的优雅选择。
但请注意:将表单存储为私有(private)的“解决方案”根本不起作用。请记住,Spring Controller 是单例 bean,因此现在这个单一表单模型实例将用于站点上的每个并发请求,从而有效地使它们共享提交的数据。
关于java - Thymeleaf + Spring MVC 发布/重定向/获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33760007/