6

Good day, I'm learning Spring MVC and I'm writting my tiny webapp following this tutorial but I slightly modified it as a "list of tasks" and not "list of users". One thing is not clear to me so I'd like to ask for an explanation. This is my 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>

And this is method editTask in my HomePageController.java (version 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;
 }

If I click on edit link to edit an item (e.g. /TaskBook/edit?id=1) a form appears but it is not populated. So I changed the method this way (version 2):

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

Now the form is populated when I edit a task. I don't understand what's the difference between model.addObject("task", task) in version 1 and model.addAttribute("task", task) in version 2. Is the task object stored somewhere else or is it lost? Please explain. I use Spring Framework 3.2.1.

Thank you in advance. Vojtech.

EDIT: If I change editTask() to code below it works - the form is populated. But what if some task data were submited, how can I read them now?

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

1 に答える 1

14

あまり頻繁に発生しないエッジ ケースに遭遇しました。試しに行きましょう

@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 を a とともに使用して、レンダリングまたは転送するビューのタイプ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メソッドを呼び出す (リフレクション) ときにそれを引数として渡します。作成、追加、および返されるオブジェクトは、要求に対して Spring によって管理される に含まれるオブジェクトModelAndViewとマージされます。したがって、ここに追加したものも後で利用できるようになります。ModelAndViewModelAndViewContainer

ヒッチ:モデル属性が優先されるように見えるため、オブジェクトModelAttributeに追加するモデル属性によって上書きされません。ModelAndView実際ModelAndViewは、属性を上書きしてオブジェクトに書き込まれます"task"。注釈にvalue属性を指定しない場合、引数の型を使用して名前が付けられることに注意してください。@ModelAttributeたとえば、Task==> "task"List<Task==>taskListなどです。

于 2013-10-04T15:25:23.957 に答える