15

我试图通过 RedirectionAttributes 传递 BindingResult:

我已经引用了Spring - 在 POST 之后重定向(即使有验证错误),但仍然卡住了。

我有一个 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

任何帮助将非常感激。

4

4 回答 4

20

这类似于 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;
    }
}
于 2013-09-27T13:06:45.707 回答
6

这绝不是一个好的答案,而是一种解决方法:

我必须将 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";
    }
}

我希望其他人找到更好的答案。

于 2013-04-10T09:19:21.673 回答
5

你的 GET 方法应该喜欢

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(final Model model)
{
    if(!model.containsAttribute("exampleForm")){
        model.addAttribute("exampleForm", new ExampleForm());
    }
    return "test";
}
于 2016-06-14T13:32:37.927 回答
4

另一种可以解决问题的方法。会话属性有助于在请求之间持久化对象,因此以下基于它

@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";
}
}
于 2013-04-12T08:50:35.980 回答