我试图通过RedirectionAttributes传递BindingResult:
我引用了Spring - Redirect after POST (even with validation errors),但仍然卡住了。
我有一个GET方法:
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(@ModelAttribute("exampleForm") final ExampleForm exampleForm, final Model model)
{
return "test";
}
和POST方法:
@RequestMapping(value = "/doSomething", method = RequestMethod.POST)
public String doSomething(@Valid @ModelAttribute("exampleForm") final ExampleForm exampleForm, final BindingResult bindingResult, final RedirectAttributes redirectAttributes)
{
if (bindingResult.hasErrors())
{
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.exampleForm", bindingResult);
redirectAttributes.addFlashAttribute("exampleForm", exampleForm);
return "redirect:/test";
}
}
但是,当我在POST方法中收到它们时,我没有看到GET方法模型中的绑定错误(重定向之后) - 它们似乎消失了。
这是POST方法中的bindingResult对象:
org.springframework.validation.BeanPropertyBindingResult: 1 errors
以下是GET方法中的模型条目,显示0个错误:
org.springframework.validation.BindingResult.exampleForm=org.springframework.validation.BeanPropertyBindingResult: 0 errors
非常感谢任何帮助。
答案 0 :(得分:12)
这类似于Cyril Deba的回答,但您可以使用flash属性而不是@SessionAttributes来实现。关键是看起来如果你把@ModelAttribute放在GET RequestMapping方法上制作表单,它就不会保留重定向flash属性的数据,但是如果你让新的表单对象进入模型中它自己的方法,然后它只在模型尚未包含它时才使用它。我还没有找到Spring的文档,说它以这种方式工作,或者为什么它们似乎工作不同,但是类似下面的工作:
@Controller
public class MyFormController {
@ModelAttribute("myForm")
public MyForm newMyForm() {
return new MyForm();
}
@RequestMapping(value = "/myForm/", method = RequestMethod.GET)
public String showMyForm() {
return "myForm";
}
@RequestMapping(value = "/myForm/", method = RequestMethod.POST)
public String processMyForm(
@Valid @ModelAttribute("myForm") final MyForm myForm,
final BindingResult bindingResult,
final RedirectAttributes redirectAttributes) {
final String view;
if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.myForm", bindingResult);
redirectAttributes.addFlashAttribute("myForm", myForm);
view = "redirect:/myForm/";
} else {
// Success
view = "redirect:/";
}
return view;
}
}
答案 1 :(得分:3)
这绝不是一个好的答案,而是一个解决方法:
我必须将flashAttribute设置为“exampleFormBindingResult”,然后覆盖模型“org.springframework.validation.BindingResult.exampleForm”属性
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(@ModelAttribute("exampleForm") final ExampleForm exampleForm, final Model model)
{
if (model.asMap().containsKey("exampleFormBindingResult"))
{
model.addAttribute("org.springframework.validation.BindingResult.exampleForm",
model.asMap().get("exampleFormBindingResult"));
}
return "test";
}
我添加了一个带有“exampleFormBindingResult”键的flashAttribute:
@RequestMapping(value = "/doSomething", method = RequestMethod.POST)
public String doSomething(@Valid @ModelAttribute("exampleForm") final ExampleForm exampleForm, final BindingResult bindingResult, final RedirectAttributes redirectAttributes)
{
if (bindingResult.hasErrors())
{
redirectAttributes.addFlashAttribute("exampleFormBindingResult", bindingResult);
redirectAttributes.addFlashAttribute("exampleForm", exampleForm);
return "redirect:/test";
}
}
我希望别人找到更好的答案。
答案 2 :(得分:3)
可以解决问题的另一种方法。会话属性有助于在请求之间保留对象,因此基于它的以下内容
@Controller
@SessionAttributes(
{ "exampleForm" })
public class HomeController
{
@ModelAttribute("exampleForm")
public ExampleForm getExampleForm()
{
return new ExampleForm();
}
@RequestMapping(value = "/myform", method = RequestMethod.POST)
public String proccessForm(@Valid @ModelAttribute("exampleForm")
final ExampleForm form, final BindingResult result,
final SessionStatus sessionStatus)
{
if (result.hasErrors())
{
return "redirect:/myform";
}
sessionStatus.setComplete();
return "redirect:/complete";
}
@RequestMapping(value = "/myform", method = RequestMethod.GET)
public String showForm(final Model model)
{
return "form";
}
@RequestMapping(value = "/complete", method = RequestMethod.GET)
public String showSomething(final Model model)
{
return "complete";
}
}
答案 3 :(得分:3)
您的GET方法应该如此
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(final Model model)
{
if(!model.containsAttribute("exampleForm")){
model.addAttribute("exampleForm", new ExampleForm());
}
return "test";
}