小编典典

ModelAndView.addObject与Model.addAttribute

spring-mvc

美好的一天,我正在学习Spring MVC,并在本教程之后编写了我的小型Web应用程序,但是我将其略微修改为“任务列表”而不是“用户列表”。我不清楚一件事,所以我想请您解释一下。这是我的edit.jsp:

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<html>
<head>
    <title>Edit task</title>
</head>
<body>
    <h1>Edit task</h1>
    <form:form method="post" action="/update" modelAttribute="task">
        <table>
            <tr>
                <td>Title</td>
                <td><form:input path="title"/></td>
            </tr>
            <tr>
                <td>Description</td>
                <td><form:textarea path="description"/></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="Save"/></td>
            </tr>
        </table>
    </form:form>
</body>
</html>

这是我的HomePageController.java(版本1)中的方法editTask:

 @RequestMapping("/edit")  
 public ModelAndView editTask(@RequestParam String id, @ModelAttribute Task task) {  
   // Retrieve task from the database
     task = taskService.getTask(id);
     ModelAndView model = new ModelAndView("edit");
     model.addObject("task", task);
     return model;
 }

如果我单击编辑链接来编辑项目(例如/ TaskBook / edit?id =
1),则会显示一个表单,但不会填充该表单。因此,我以这种方式(版本2)更改了方法:

 @RequestMapping("/edit")  
 public String editTask(@RequestParam String id, Model model) {
     Task task = taskService.getTask(id);
     model.addAttribute("task", task);
     return "edit";
 }

现在,当我编辑任务时,将填充表格。我不了解版本1中的model.addObject(“
task”,task)和版本2中的model.addAttribute(“
task”,task)有什么区别?任务对象存储在其他位置还是丢失了?请解释。我使用Spring Framework 3.2.1。

先感谢您。Vojtech。

编辑:如果我将editTask()更改为下面的代码,则可以正常工作-填充表格。但是,如果提交了一些任务数据该怎么办,我现在如何读取它们?

@RequestMapping("/edit")  
public ModelAndView editTask(@RequestParam String id) {  
  task = taskService.getTask(id);
  ModelAndView model = new ModelAndView("edit");
  model.addObject("task", task);
  return model;
}

阅读 748

收藏
2020-06-01

共1个答案

小编典典

您遇到的情况很少发生。让我们去尝试

@RequestMapping("/edit")  
public String editTask(@RequestParam String id, Model model) {
    Task task = taskService.getTask(id);
    model.addAttribute("task", task);
    return "edit";
}

在这种情况下,Spring将Model根据其创建一个对象ModelAndViewContainer,并将其作为参数传递给您的方法。因此,如果您之前添加了模型属性,则可以在此处使用它们,而以后添加的属性也可以使用。您返回一个String视图名称。Spring将使用带有String的String
ViewResolver来解析jsp要呈现或转发到的视图或其他类型的视图。

有了这个

@RequestMapping("/edit")  
public ModelAndView editTask(@RequestParam String id, @ModelAttribute Task task) {  
    // Retrieve task from the database
    task = taskService.getTask(id);
    ModelAndView model = new ModelAndView("edit");
    model.addObject("task", task);
    return model;
}

由于的原因,Spring
@ModelAttribute将创建一个Task对象,并在调用(反射)您的方法时将该对象作为参数传递。在ModelAndView您创建对象,添加和回报将与被合并ModelAndView对象中包含的ModelAndViewContainer由Spring为您的要求进行管理。因此,您在此处添加的内容也将稍后可用。

The hitch: It appears ModelAttribute has priority on the model
attributes, so it doesn’t get overwritten by the model attributes you add to
the ModelAndView object. Actually it gets written to your ModelAndView
object, overwriting your "task" attribute. Remember that if you don’t
specify a value attribute to @ModelAttribute annotation, it uses the type
of the argument to give it a name. For example, Task ==> "task",
List<Task ==> taskList, etc.

2020-06-01