提交表单时,Spring 控制器重新加载同一页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7658457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring controller to reload same page when form is submitted
提问by user979899
I'm having a problem with creating a Spring controller that would reload the same page when a form is filled in. What I want to achieve is a page for changing passwords. It should ask for old password, a new password and the new password re-typed. When the user fills in everything and submits the form, the action should be the same page and the controller should be able to either show something like "passwords do not match" or "password successfully changed". I know how to achieve this by using several controllers but I think it would be better to use one controller.
我在创建一个 Spring 控制器时遇到问题,该控制器会在填写表单时重新加载同一页面。我想要实现的是一个用于更改密码的页面。它应该要求输入旧密码、新密码和重新输入新密码。当用户填写所有内容并提交表单时,操作应该是同一页面,并且控制器应该能够显示诸如“密码不匹配”或“密码已成功更改”之类的内容。我知道如何通过使用多个控制器来实现这一点,但我认为使用一个控制器会更好。
Below is my controller:
下面是我的控制器:
package controllers;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import models.Password;
@Controller
public class ChangePassword {
@RequestMapping(value = "/changepassword", method = RequestMethod.GET)
public ModelAndView changePassword(@ModelAttribute("changepassword")Password password, BindingResult result) {
if(password.isEmpty())
{
return new ModelAndView("changepassword", "command", new Password());
}
else if(password.isValid())
{
return new ModelAndView("changepassword", "message", "The password was successfully changed!");
}
else{
return new ModelAndView("changepassword", "message", "The passwords did not match and/or the password was not 8 at least 8 characters long.");
}
}
The first time the page loads it shows the form correctly, but if one leave the password empty and submit then glassfish shows:
页面第一次加载时正确显示表单,但如果将密码留空并提交,那么 glassfish 会显示:
"org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute"
“org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是 java.lang.IllegalStateException:对于 bean 名称‘command’既没有 BindingResult 也没有普通目标对象作为请求属性可用”
I don't understand why this happens, I thought it should show the form like the first time accessed.
我不明白为什么会发生这种情况,我认为它应该像第一次访问一样显示表单。
In fact what I need is to get the Password model to the viewer and also some text (error message or successfull message). I have seen people returning maps to the viewer but I haven't succeeded doing that.
事实上,我需要的是将密码模型提供给查看器以及一些文本(错误消息或成功消息)。我见过人们将地图返回给观众,但我没有成功做到这一点。
回答by danny.lesnik
You should map request as GET and POST. GET for rendering page and its messages and POST for the submit itself.
您应该将请求映射为 GET 和 POST。GET 用于呈现页面及其消息,POST 用于提交本身。
You should redirect to avoid Duplicate submit problem.
您应该重定向以避免重复提交问题。
and in order to show message in model and view you should use FlashScope implementation.
为了在模型和视图中显示消息,您应该使用 FlashScope 实现。
See this post for details: Spring MVC custom scope bean
有关详细信息,请参阅此帖子: Spring MVC custom scope bean
You can do it this way:
你可以这样做:
@Controller
public class ChangePassword {
@RequestMapping(value = "/changepassword", method = RequestMethod.GET)
public ModelAndView renderCPassPage(@ModelAttribute("changepassword")Password password, BindingResult result) {
ModelAndView mv = new ModelAndView("changePassword");
mv.addObject("password" password);
return mv;
}
@RequestMapping(value = "/changepassword", method = RequestMethod.POST)
public ModelAndView renderCPassPage(@ModelAttribute("changepassword")Password password, BindingResult result) {
ModelAndView mv = new ModelAndView("redirect:changepassword");
if(password.isEmpty())
{
return new ModelAndView("message", "password Empty");
}
else if(password.isValid())
{
return new ModelAndView("message", "The password was successfully changed!");
}
else{
return new ModelAndView("message", "The passwords did not match and/or the password was not 8 at least 8 characters long.");
}
}

