Java Spring MVC在控制器之间传递相同的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21426519/
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 MVC pass same object between controller
提问by Pratik Shelar
In Spring MVC how do I pass an object between two controller methods? I have an update form and an updateController. In the controller I have 2 methods, one for fetching the data and displaying it in a view. The second method of the controller is invoked when the user clicks update button with modified changes. What I am observing is that the object which I get in second method of the controller is not the same object which I passed to the view in the first controller method call. Its a new object altogether with all form fields mapped to it. How do I make sure that the same object is passed to the second controller method which was provided to the view by the first controller method?
在 Spring MVC 中,如何在两个控制器方法之间传递对象?我有一个更新表单和一个 updateController。在控制器中,我有两种方法,一种用于获取数据并将其显示在视图中。当用户单击带有修改更改的更新按钮时,将调用控制器的第二个方法。我观察到的是,我在控制器的第二个方法中获得的对象与我在第一个控制器方法调用中传递给视图的对象不同。它是一个新对象,所有表单字段都映射到它。如何确保将相同的对象传递给由第一个控制器方法提供给视图的第二个控制器方法?
@RequestMapping(value = "/showEmpDetail.html", method = RequestMethod.GET)
public String showEmpDetails(
@RequestParam(value = "page", required = false) Integer page,
HttpServletRequest request, @RequestParam("empId") Long empId,
ModelMap model) {
// Get employee using empId from DB
model.addAttribute("emp",emp);
return "showEmpDetail";
}
The above controller method gets the emp values from Db and displays it correctly in the view. Now the user changes some details and clicks submit button. The following controller method is called.
上面的控制器方法从 Db 中获取 emp 值并在视图中正确显示它。现在用户更改了一些细节并点击提交按钮。调用以下控制器方法。
@RequestMapping(value = "/editEmpFormSubmission.html", method = RequestMethod.POST)
public String editEmpFormSubmission(
@RequestParam(value = "page", required = false) Integer page,
@ModelAttribute("emp") Employee emp, BindingResult result,
ModelMap model, HttpServletRequest request) {
// update changes in DB
}
In the above controller method when I check the emp object its not the same object which I passed in previous controller call. The fields which are not form backed but had values were changed to null. How can I make sure the same object is passed by view. I do not want to add the object as sessionAttribute since a user might modify many employees in a session.
在上面的控制器方法中,当我检查 emp 对象时,它与我在之前的控制器调用中传递的对象不同。没有表单支持但有值的字段被更改为空。如何确保视图传递相同的对象。我不想将对象添加为 sessionAttribute,因为用户可能会在会话中修改许多员工。
回答by Tarmo
How can I make sure the same object is passed by view. I do not want to add the object as sessionAttribute since a user might modify many employees in a session
如何确保视图传递相同的对象。我不想将对象添加为 sessionAttribute,因为用户可能会在会话中修改许多员工
You could make a field in the object that is filled with a random number at the time of initial render and then store that object in the session. In the view you can map that field with a hidden input and now when user sends a request to edit action you can get that hidden field and fetch the original object from session by the number in the hidden field. That would resolve the multiple edits in different tabs conflict.
您可以在初始渲染时用随机数填充的对象中创建一个字段,然后将该对象存储在会话中。在视图中,您可以使用隐藏输入映射该字段,现在当用户发送编辑操作请求时,您可以获取该隐藏字段并通过隐藏字段中的数字从会话中获取原始对象。这将解决不同选项卡中的多个编辑冲突。
回答by M. Deinum
You have 3 options
你有3个选择
- Use
@SessionAttributes
to store the object in the session in between requests. - Use a
@ModelAttribute
annotated method to retrieve the object before each request - Write your own code and store it in the session (similair to 1 but more work on your part).
- 用于
@SessionAttributes
在请求之间的会话中存储对象。 @ModelAttribute
在每次请求之前使用带注释的方法检索对象- 编写您自己的代码并将其存储在会话中(类似于 1,但您需要做更多的工作)。
Option 1
选项1
- Add the
@SessionAttributes
annotation to your controller class - Add the
SessionStatus
as a parameter to your update method and thesetComplete()
method when you are finished with the object
- 将
@SessionAttributes
注释添加到您的控制器类 - 将
SessionStatus
作为参数添加到更新方法和setComplete()
完成对象后的方法
@SessionAttributes("emp")
public class EmployeeController {
@RequestMapping(value = "/editEmpFormSubmission.html", method = RequestMethod.POST)
public String editEmpFormSubmission(
@RequestParam(value = "page", required = false) Integer page,
@ModelAttribute("emp") Employee emp, BindingResult result,
ModelMap model, HttpServletRequest request
SessionStatus status) {
// update changes in DB
status.setComplete();
}
}
Option 2
选项 2
- Add the method which retrieves the object from the database and annotate it with
@ModelAttribute
- Cleanup your
showEmpDetails
method as it should only return a view name
- 添加从数据库中检索对象并使用注释的方法
@ModelAttribute
- 清理你的
showEmpDetails
方法,因为它应该只返回一个视图名称
public class EmployeeController {
@ModelAttribute("emp")
public Employee getEmployee(@RequestParam("empdId") Long id) {
// Get employee using empId from DB
return emp;
}
@RequestMapping(value = "/showEmpDetail.html", method = RequestMethod.GET)
public String showEmpDetails() {) {
return "showEmpDetail";
}
}
Option 3
选项 3
- In your methods add the
HttpSession
as an argument - In your
showDetails
method next to adding it to the model add it to the session - In your
editEmpFormSubmission
use the one from the session and copy all non-null fields to the object from the session and store that in the database.
- 在您的方法中添加
HttpSession
作为参数 - 在您
showDetails
将其添加到模型旁边的方法中,将其添加到会话中 - 在您
editEmpFormSubmission
使用会话中的一个并将所有非空字段从会话复制到对象并将其存储在数据库中。
I wouldn't go for option, I strongly would suggest option 1 especially including the setComplete()
on the SessionStatus
object for cleanup. You could also combine 1 and 2 (have a @ModelAttribute
annotated method and still use @SessionAttributes
.).
我不会选择,我强烈建议选项 1,特别是包括用于清理setComplete()
的SessionStatus
对象。你也可以结合 1 和 2(有一个带@ModelAttribute
注释的方法并且仍然使用@SessionAttributes
.)。