我有一个弹簧控制器UserController
,我有以下方法(不包括业务逻辑):
@RequestMapping(value = "new", method = RequestMethod.GET)
public String getNewUserForm(Model model) {
model.addAttribute("action", "Create");
model.addAttribute(new User());
return "users/edit";
}
@RequestMapping(value = "create", method = RequestMethod.POST)
public String getCreateUser(@ModelAttribute("user") User user, BindingResult result, RedirectAttributes attr) {
attr.addFlashAttribute("user", user);
return "redirect:view";
}
@RequestMapping(value = "view", method = RequestMethod.GET)
public String getViewUser(Model model) {
return "users/view";
}
我最终得到了三个“动作”(新建,创建和视图)。我想要实现的目标如下:在浏览器中输入app.com/users/new
。将显示创建用户表单users/edit
。提交表单后,会调用users/create (POST)
。成功创建用户后,我想将用户转发到users/view
,并在不可编辑的页面中显示输入数据。我不能只返回view
,因为网址仍为app.com/users/create
。我想阅读app.com/users/view
。
现在,我正在使用RedirectAttributes
对象,并返回redirect:view
并且它有效。但感觉应该有更好的方法来实现这一目标。我尝试使用不redirect:view
的{{1}},但模型不可用。
另一种方法是在url中传递用户标识(例如:RedirectAttributes
)并从数据库加载数据。但考虑到我已经拥有该对象的最新版本,这似乎是对数据库的不必要的往返。我将为“漂亮的网址”实现此功能,但我不想选择不加载用户对象(如果可用)。
这样的事情:
app.com/users/view/1
我的方法是推荐的吗?或者我是否完全错误地看待这个?
答案 0 :(得分:5)
更好的方法是重定向到app.com/users/view/1
。
首先,因为您对模型进行了最新的更改,而不是另一个并发用户可能同时进行的更改。
其次,因为它使您的应用程序无状态,因此同时更具可扩展性和简单性。
第三,因为视图页面可能需要比编辑页面更多的用户信息。有一个大的详细信息页面显示用户的许多关联,但在编辑页面中只有一些可修改的信息。因此,保存编辑页面的模型以使其可用于视图页面是不够的。
第四,因为这样,显示用户细节的逻辑就在一个地方,并且只有一个可能的URL可以做到这一点。
第五,因为这样,用户可以将URL加入书签,或通过电子邮件将其发送给某人,如果他稍后返回此URL,它将起作用。在您当前的解决方案中,只有在您之前编辑过用户时,URL才有效。