Spring - POST后重定向(即使有验证错误)

Tay*_*ese 61 java validation google-app-engine spring spring-mvc

我试图弄清楚如何"保留"BindingResult,以便它可以通过Spring <form:errors>标签用于后续的GET .我想这样做的原因是因为Google App Engine的SSL限制.我有一个通过HTTP显示的表单,帖子是一个HTTPS URL.如果我只转发而不是重定向,那么用户将看到https://whatever.appspot.com/my/form URL.我试图避免这种情况.任何想法如何处理这个?

以下是我想做的事情,但我在使用时只看到验证错误return "create".

@RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(
    @ModelAttribute("register") @Valid final Register register,
    final BindingResult binding) {

    if (binding.hasErrors()) {
        return "redirect:/register/create";
    }

    return "redirect:/register/success";
}
Run Code Online (Sandbox Code Playgroud)

Osc*_*car 70

从Spring 3.1开始,您可以使用RedirectAttributes.在执行重定向之前添加要提供的属性.添加BindingResult和用于验证的对象,在本例中为Register.

对于BindingResult,您将使用名称:"org.springframework.validation.BindingResult.[ModelAttribute的名称]".

对于用于验证的对象,将使用ModelAttribute的名称.

要使用RedirectAttributes,您必须在配置文件中添加它.除了其他事情,你告诉Spring使用一些较新的类:

<mvc:annotation-driven />
Run Code Online (Sandbox Code Playgroud)

现在,无论您何时重定向,都会显示错误

@RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(@ModelAttribute("register") @Valid final Register register, final BindingResult binding, RedirectAttributes attr, HttpSession session) {

if (binding.hasErrors()) {
    attr.addFlashAttribute("org.springframework.validation.BindingResult.register", binding);
    attr.addFlashAttribute("register", register);
    return "redirect:/register/create";
}

return "redirect:/register/success";
}
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,RedirectAttributes不能与(过时的?)ModelAndView概念一起使用.他们假设您的方法返回一个简单的字符串,如上例所示. (3认同)
  • 这样做时我得到错误:java.io.NotSerializableException:org.springframework.format.support.DefaultFormattingConversionService (2认同)

Utk*_*mir 57

除了奥斯卡的好答案之外,如果您遵循这种RedirectAttributes方法,请不要忘记您实际上正在将modelAttribute其传递到重定向页面.这意味着如果为重定向页面(在控制器中)创建该modelAttribute的新实例,则将丢失验证错误.所以,如果您的POST控制器方法是这样的:

@RequestMapping(value = "/submit", method = RequestMethod.POST)
public final String submit(@ModelAttribute("register") @Valid final Register register, final BindingResult binding, RedirectAttributes attr, HttpSession session) {

if (binding.hasErrors()) {
    attr.addFlashAttribute("org.springframework.validation.BindingResult.register", binding);
    attr.addFlashAttribute("register", register);
    return "redirect:/register/create";
}

return "redirect:/register/success";
}
Run Code Online (Sandbox Code Playgroud)

然后你可能需要在你的寄存器创建页面GET控制器中进行修改.由此:

@RequestMapping(value = "/register/create", method = RequestMethod.GET)
public String registerCreatePage(Model model) {
    // some stuff
    model.addAttribute("register", new Register());
    // some more stuff
}
Run Code Online (Sandbox Code Playgroud)

@RequestMapping(value = "/register/create", method = RequestMethod.GET)
public String registerCreatePage(Model model) {
    // some stuff
    if (!model.containsAttribute("register")) {
        model.addAttribute("register", new Register());
    }
    // some more stuff
}
Run Code Online (Sandbox Code Playgroud)

资料来源:http://gerrydevstory.com/2013/07/11/preserving-validation-error-messages-on-spring-mvc-form-post-redirect-get/

  • 常见的陷阱:将"org.springframework.validation.BindingResult.register"中的"register"更改为modelAttribute的名称 (6认同)
  • 如果您无法访问gerrydevstory.com上的源文章,这里有一个存档版本:http://web.archive.org/web/20160606223639/https://gerrydevstory.com/2013/07/11/preserving -validation错误的消息,上弹簧MVC-表单提交重定向消息获得/ (5认同)

Ich*_*ato -1

也许这有点简单,但是您是否尝试过将其添加到您的模型中?即,将模型包含在方法的参数中,然后将 BindingResult 添加到其中,然后在您的视图中可用。

model.addAttribute("binding",binding);
Run Code Online (Sandbox Code Playgroud)

我认为你可能必须使用转发而不是重定向(在我的脑海中,我不记得重定向是否会丢失会话 - 我对此可能是错误的,因为我没有任何方便的文档,即,如果将 BindingResult 添加到模型后,您没有获得 BindingResult,请尝试使用转发来确认这一点)。