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   3  

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, и т.д.