ModelAndView.addObject vs Model.метод addattribute
Добрый день, я изучаю Spring MVC и пишу свое крошечное веб-приложение послеэтого урока , но я немного изменил его как "список задач", а не "список пользователей". Одна вещь мне не ясна, поэтому я хотел бы попросить объяснений. Это моя правка.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>
И это метод editTask в моем HomePageController.java (Версия 1):
@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";
}
Теперь форма заполняется, когда я редактирую задачу. Я не понимаю, в чем разница между моделями.addObject ("задача", task) в версии 1 и модели.addAttribute ("task", задача) в версии 2. Объект задачи хранится где-то еще или он потерян? Пожалуйста объяснить. Я использую Spring Framework 3.2.1.
Заранее благодарю вас. Войтех.
Править: Если я изменю editTask () на код ниже, он работает - форма заполняется. Но что, если некоторые данные задачи были отправлены, как я могу прочитать их сейчас?
@RequestMapping("/edit")
public ModelAndView editTask(@RequestParam String id) {
task = taskService.getTask(id);
ModelAndView model = new ModelAndView("edit");
model.addObject("task", task);
return model;
}
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 будет использовать эту строку с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 для вашего запроса. Таким образом, то, что вы добавляете здесь, также будет доступно позже.Загвоздка: похоже, что
ModelAttributeимеет приоритет над атрибутами модели, поэтому он не перезаписывается моделью атрибуты, добавляемые к объектуModelAndView. На самом деле Он записывается в вашModelAndViewобъект, перезаписывая ваш"task"атрибут. Помните, что если вы не задаете атрибутvalueдля аннотации@ModelAttribute, он использует тип аргумента, чтобы дать ему имя. Например:,Task==>"task",List<Task==>taskList, и т.д.