我有一个包含Spring表单的JSP。在呈现JSP之前,将在控制器中添加表单的命令对象。 Spring将JSP中的表单绑定到此命令对象,并在提交新实例时正确处理它。
但是,我想通过DWR(也可以正常工作)保持命令对象,然后将表单提交给控制器。在将表单提交给控制器时,命令对象不再是新对象,而是需要更新的持久对象。这是我希望表单元素自动绑定到命令对象并通过绑定更新的地方,但它们没有被绑定。
SIMPLE示例:我将向Task
添加一个新的ModelMap
,以便Spring表单将绑定到该命令对象。但是,我不会提交新的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();
}
}
Spring Form
<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绑定命令对象设置为持久对象?
答案 0 :(得分:3)
使用注释实际上有更好的方法。
创建一个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);
...
}
答案 1 :(得分:1)
当使用@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();
}
Spring 2.5.x documentation of WebRequestDataBinder
是您可以找到Juergen Hoeller's此类应用程序的'手动数据绑定'示例。
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();
...