是否有可能弹簧结合之前手动设置在@RequestMapping方法命令对象?
-
21-08-2019 - |
题
我有具有弹簧的形式在它一个JSP。窗体的命令对象在控制器添加的JSP呈现之前。结合春季在JSP形式此命令对象,并提交一个新的实例时,会正确地处理它。
然而,我想持续经由DWR命令对象(其也工作正常),然后提交表单到控制器。在表单被提交到控制器的点,命令对象不再是一个新的对象,而是一个需要持久化的对象进行更新。这就是我想要的形式的元素来自动绑定到命令对象,并经由所述结合被更新,但它们不被约束。
简单的例子:我将增加一个新Task
到ModelMap
,从而弹簧形式将结合到该命令对象。然而,代替提交新Task
,我将坚持通过DWR新Task
,这将返回的ID,然后继续的形式提交到控制器之前编辑任务。
<强>控制器类强>
@Controller
public class ProjectController {
/**
* This adds the "task" command object to the session attributes and loads
* the initial form.
*/
@RequestMapping(value="/project", method=RequestMethod.GET)
public String setupForm(@RequestParam(value="id", required=true) String id,
HttpServletRequest request, ModelMap modelMap) {
modelMap.addAttribute("project", projectRepo.get(id));
modelMap.addAttribute("task", new Task());
return "/project/task";
}
/**
* This processes the form submit, and should update the Task.
*/
@RequestMapping(value="/project/task/update", method=RequestMethod.POST)
public String updateTask(@ModelAttribute(value="task") Task task,
@RequestParam(value="taskId") String taskId,
HttpServletRequest request, ModelMap modelMap) {
// BEFORE binding the parameters to the command object (task),
// I want to assign the command object as the one already persisted.
task = taskRepo.get(taskId);
// NOW, I want the request parameters to be bound to the task command object.
// HOW ?????????
// Persist the changes.
taskRepo.merge(task);
// BACK to the setupForm method/form view
return "/project?id=" + task.getProject().getId();
}
}
<强>弹簧表格强>
<form:form commandName="task" method="post" action="/project/task/update" id="taskForm">
<form:hidden path="id" id="task.id"/>
<form:input path="name" id="task.name"/>
<!-- DWR will save the task (save and continue), then will return the id. -->
<!-- After saved, the user can still change the name,
then submit the form for processing by the controller -->
</form:form>
可以一个Spring绑定命令对象之前被设置成持久对象的任何后提交绑定发生?
解决方案
实际上有更好的方法来做到这一点使用注解。
创建的ModelAttribute方法,它返回您从存储库所需的命令对象。强>
@ModelAttribute("task")
public Task task(@RequestParam(value = "id", required = true) String id) {
return taskRepo.get(taskId);
}
,然后,只需将的ModelAttribute添加到表单提交方法。强>
@RequestMapping(value="/project/task/update", method=RequestMethod.POST)
public String updateTask(@ModelAttribute(value="task") Task task,
HttpServletRequest request, ModelMap modelMap) {
taskRepo.merge(task);
...
}
其他提示
看来,使用@ModelAttribute
访问命令对象,即可以访问命令对象之前结合时发生。为了设置该命令对象要从形式结合请求参数之前什么,简单地传递在属性的ID和从数据库中抓住它,然后结合的WebRequest参数。
<强>在POST方法强>
@RequestMapping(value="/project/task/update", method=RequestMethod.POST)
public String updateTask(@ModelAttribute(value="task") Task task,
@RequestParam(value="taskId") String taskId,
HttpServletRequest request, ModelMap modelMap) {
// BEFORE binding the parameters to the command object (task),
// I want to assign the command object as the one already persisted.
task = taskRepo.get(taskId);
// NOW, I want the request parameters to be bound to the task command object.
WebRequestDataBinder binder = new WebRequestDataBinder(task);
ServletWebRequest webRequest = new ServletWebRequest(request);
binder.bind(webRequest);
// Persist the changes.
taskRepo.merge(task);
// BACK to the setupForm method/form view
return "/project?id=" + task.getProject().getId();
}
在 WebRequestDataBinder
春季2.5.X文档,你可以找到克林斯曼Hoeller 的例子的“手动数据绑定”的这种类型的应用。
MyBean myBean = new MyBean();
// apply binder to custom target object
WebRequestDataBinder binder = new WebRequestDataBinder(myBean);
// register custom editors, if desired
binder.registerCustomEditor(...);
// trigger actual binding of request parameters
binder.bind(request);
// optionally evaluate binding errors
Errors errors = binder.getErrors();
...
不隶属于 StackOverflow