2

我有一个 JSP,其中有一个 Spring 表单。在呈现 JSP 之前,将表单的命令对象添加到控制器中。Spring 将 JSP 中的表单绑定到这个命令对象,并在提交 NEW 实例时正确处理它。

但是,我想通过 DWR 保留命令对象(也可以正常工作),然后将表单提交给控制器。在表单提交给控制器的那一刻,命令对象不再是一个新对象,而是一个需要更新的持久化对象。这是我希望表单元素自动绑定到命令对象并通过绑定进行更新的地方,但它们没有被绑定。

简单示例:我将向 中添加一个新TaskModelMap,以便 Spring 表单将绑定到该命令对象。但是,我不会提交新的,而是通过 DWRTask持久化新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 绑定命令对象设置为持久对象吗?

4

2 回答 2

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);
    ...
}
于 2009-05-19T13:37:01.580 回答
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 文档中WebRequestDataBinder找到Juergen 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();
...
于 2009-05-15T14:49:32.793 回答