美好的一天,我正在学习Spring MVC,我正在this tutorial之后编写我的小型webapp,但我稍微修改了它作为“任务列表”而不是“用户列表”。有一件事我不清楚,所以我想请一个解释。这是我的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(“任务”,任务)和版本2中的model.addAttribute(“任务”,任务)之间有什么区别。任务对象是存储在其他地方还是丢失了?请解释。我使用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;
}
答案 0 :(得分:12)
你遇到了一个不经常发生的边缘情况。我们一起来试试
@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将使用带有ViewResolver
的String来解析要呈现或转发的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
对象将与Spring为您的请求管理的ModelAndView
中包含的ModelAndViewContainer
对象合并。因此,您在此处添加的内容也将在稍后提供。
故障:似乎ModelAttribute
优先考虑模型属性,因此不会被添加到ModelAndView
对象的模型属性覆盖。实际上它会写入您的ModelAndView
对象,覆盖您的"task"
属性。请记住,如果您没有为value
注释指定@ModelAttribute
属性,它会使用参数类型为其命名。例如,Task
==&gt; "task"
,List<Task
==&gt; taskList
等等。