spring-mvc - ModelAndView.addObject与Model.addAttribute

标签 spring-mvc

美好的一天,我正在学习Spring MVC,并且在this tutorial之后编写了我的小型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;
}

最佳答案

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

@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 View 名称。 Spring将使用带有ViewResolver的String来解析要呈现或转发到的jsp或其他类型的 View 。

有了这个
@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 ==> "task"List<Task ==> taskList等。

关于spring-mvc - ModelAndView.addObject与Model.addAttribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19183747/

相关文章:

java - Spring Mvc 中 jQuery Ajax 中的 JSON 响应

java - 什么时候使用 getAutowireCapableBeanFactory().autowireBean(someBean)?

java - 来自数据库的消息包 Spring MVC 3

java - 如何在 boot application.properties 中使用 spring 设置 velocity 布局目录和默认模板

java - Spring Boot Web 应用程序加载由另一个应用程序创建的新网页

java - Springboot的@Controller和@RestController注解什么时候用,底层概念是什么?

java - javascript 中的重定向到 JSP 不起作用(使用 Spring MVC)

spring - 在JSP页面中获取用户名。主体.用户名不起作用

java - 在 Spring 中返回一个没有重定向的静态 html

java - Spring MVC - AJAX/JSON - ResponseBody -> 调用服务