@ModelAttribute注解,什么时候使用它?

发布于 2024-12-24 01:08:53 字数 2090 浏览 1 评论 0原文

假设我们有一个实体 Person、一个控制器 PersonController 和一个 edit.jsp 页面(创建一个新的或编辑现有的 person)

控制器

@RequestMapping(value = "/edit", method = RequestMethod.POST)
public String editPerson(@RequestParam("fname") String fname, Model model) {
    if(fname == null || fname.length() == 0){
        model.addAttribute("personToEditOrCreate", new Person());
    }
    else{
        Person p = personService.getPersonByFirstName(fname);
        model.addAttribute("personToEditOrCreate", p);
    }

    return "persons/edit";
}

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePerson(Person person, BindingResult result) {

    personService.savePerson(person);
    return "redirect:/home";
}

edit.jsp

<form:form method="post" modelAttribute="personToEditOrCreate" action="save">
    <form:hidden path="id"/> 
    <table>
        <tr>
            <td><form:label path="firstName">First Name</form:label></td>
            <td><form:input path="firstName" /></td>
        </tr>
        <tr>
            <td><form:label path="lastName">Last Name</form:label></td>
            <td><form:input path="lastName" /></td>
        </tr>
        <tr>
            <td><form:label path="money">Money</form:label></td>
            <td><form:input path="money" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="Add/Edit Person"/>
            </td>
        </tr>
    </table> 

</form:form>

我正在尝试上面的代码(没有在 savePerson 方法中使用 @ModelAttribute 注释,并且它工作正确。为什么以及何时需要将注释添加到 person 对象:

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePerson(@ModelAttribute("personToEditOrCreate") Person person, BindingResult result) {

    personService.savePerson(person);
    return "redirect:/home";
}

Lets say we have an entity Person, a controller PersonController and an edit.jsp page (creating a new or editing an existing person)

Controller

@RequestMapping(value = "/edit", method = RequestMethod.POST)
public String editPerson(@RequestParam("fname") String fname, Model model) {
    if(fname == null || fname.length() == 0){
        model.addAttribute("personToEditOrCreate", new Person());
    }
    else{
        Person p = personService.getPersonByFirstName(fname);
        model.addAttribute("personToEditOrCreate", p);
    }

    return "persons/edit";
}

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePerson(Person person, BindingResult result) {

    personService.savePerson(person);
    return "redirect:/home";
}

edit.jsp

<form:form method="post" modelAttribute="personToEditOrCreate" action="save">
    <form:hidden path="id"/> 
    <table>
        <tr>
            <td><form:label path="firstName">First Name</form:label></td>
            <td><form:input path="firstName" /></td>
        </tr>
        <tr>
            <td><form:label path="lastName">Last Name</form:label></td>
            <td><form:input path="lastName" /></td>
        </tr>
        <tr>
            <td><form:label path="money">Money</form:label></td>
            <td><form:input path="money" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="Add/Edit Person"/>
            </td>
        </tr>
    </table> 

</form:form>

Im trying the code above (without using the @ModelAttribute annotation in the savePerson method, and it works correct. Why and when do i need to add the annotation to the person object:

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePerson(@ModelAttribute("personToEditOrCreate") Person person, BindingResult result) {

    personService.savePerson(person);
    return "redirect:/home";
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紅太極 2024-12-31 01:08:53

您不需要 @ModelAttribute (parameter) 只是使用 Bean 作为参数

例如,这些处理程序方法可以很好地处理这些请求:

@RequestMapping("/a")
void pathA(SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

GET /a?name=neil

@RequestMapping(value="/a", method=RequestMethod.POST)
void pathAPost(SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

POST /a
name=neil

使用 @ModelAttribute方法)在每次请求时将默认数据加载到模型中 - 例如从数据库加载,尤其是在使用@SessionAttributes时。这可以在 ControllerControllerAdvice 中完成:

@Controller
@RequestMapping("/foos")
public class FooController {

  @ModelAttribute("foo")
  String getFoo() {
    return "bar";  // set modelMap["foo"] = "bar" on every request
  }

}

FooController 转发到的任何 JSP:

${foo} //=bar

@ControllerAdvice
public class MyGlobalData {

  @ModelAttribute("foo")
  String getFoo() {
    return "bar";  // set modelMap["foo"] = "bar" on every request
  }

}

任何 JSP:

${foo} //=bar

使用 @ModelAttribute参数)如果您想使用@ModelAttribute方法)的结果作为默认

@ModelAttribute("attrib1")
SomeBean getSomeBean() {
  return new SomeBean("neil");  // set modelMap["attrib1"] = SomeBean("neil") on every request
}

@RequestMapping("/a")
void pathA(@ModelAttribute("attrib1") SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

GET /a

使用@ModelAttribute参数)获取存储在flash属性中的对象:

@RequestMapping("/a")
String pathA(RedirectAttributes redirectAttributes) {
  redirectAttributes.addFlashAttribute("attrib1", new SomeBean("from flash"));
  return "redirect:/b";
}

@RequestMapping("/b")
void pathB(@ModelAttribute("attrib1") SomeBean someBean) {
  assertEquals("from flash", someBean.getName());
}

GET /a

使用@ModelAttribute参数)获取由 @SessionAttributes 存储的对象

@Controller
@SessionAttributes("attrib1")
public class Controller1 {

    @RequestMapping("/a")
    void pathA(Model model) {
        model.addAttribute("attrib1", new SomeBean("neil")); //this ends up in session due to @SessionAttributes on controller
    }

    @RequestMapping("/b")
    void pathB(@ModelAttribute("attrib1") SomeBean someBean) {
        assertEquals("neil", someBean.getName());
    }
}

GET /a
GET /b

You don't need @ModelAttribute (parameter) just to use a Bean as a parameter

For example, these handler methods work fine with these requests:

@RequestMapping("/a")
void pathA(SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

GET /a?name=neil

@RequestMapping(value="/a", method=RequestMethod.POST)
void pathAPost(SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

POST /a
name=neil

Use @ModelAttribute (method) to load default data into your model on every request - for example from a database, especially when using @SessionAttributes. This can be done in a Controller or in a ControllerAdvice:

@Controller
@RequestMapping("/foos")
public class FooController {

  @ModelAttribute("foo")
  String getFoo() {
    return "bar";  // set modelMap["foo"] = "bar" on every request
  }

}

Any JSP forwarded to by FooController:

${foo} //=bar

or

@ControllerAdvice
public class MyGlobalData {

  @ModelAttribute("foo")
  String getFoo() {
    return "bar";  // set modelMap["foo"] = "bar" on every request
  }

}

Any JSP:

${foo} //=bar

Use @ModelAttribute (parameter) if you want to use the result of @ModelAttribute (method) as a default:

@ModelAttribute("attrib1")
SomeBean getSomeBean() {
  return new SomeBean("neil");  // set modelMap["attrib1"] = SomeBean("neil") on every request
}

@RequestMapping("/a")
void pathA(@ModelAttribute("attrib1") SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

GET /a

Use @ModelAttribute (parameter) to get an object stored in a flash attribute:

@RequestMapping("/a")
String pathA(RedirectAttributes redirectAttributes) {
  redirectAttributes.addFlashAttribute("attrib1", new SomeBean("from flash"));
  return "redirect:/b";
}

@RequestMapping("/b")
void pathB(@ModelAttribute("attrib1") SomeBean someBean) {
  assertEquals("from flash", someBean.getName());
}

GET /a

Use @ModelAttribute (parameter) to get an object stored by @SessionAttributes

@Controller
@SessionAttributes("attrib1")
public class Controller1 {

    @RequestMapping("/a")
    void pathA(Model model) {
        model.addAttribute("attrib1", new SomeBean("neil")); //this ends up in session due to @SessionAttributes on controller
    }

    @RequestMapping("/b")
    void pathB(@ModelAttribute("attrib1") SomeBean someBean) {
        assertEquals("neil", someBean.getName());
    }
}

GET /a
GET /b

明天过后 2024-12-31 01:08:53

您的问题似乎已经得到解答:

What is @ModelAttribute in Spring MVC?

总结答案和博客文章:当您希望表单支持对象(Person 的实例)在请求之间保留时。

否则,如果没有注释,请求映射方法将假定 Person 是一个新对象,并且绝不会链接到您的表单支持对象。顺便说一句,海报引用的博客文章真的很棒,绝对是必读的。

Your question appears to be answered already:

What is @ModelAttribute in Spring MVC?

To summarize the answer and blog post: when you want your form backing object (instance of Person) to be persisted across requests.

Otherwise, without the annotation, the request mapped method will assume Person is a new object and in no way linked to your form backing object. The blog post that poster references is really awesome by the way, definitely a must-read.

花开柳相依 2024-12-31 01:08:53

方法参数上的 @ModelAttribute 指示将从模型中检索该参数。如果模型中不存在该参数,则该参数将首先实例化,然后添加到模型中。

An @ModelAttribute on a method argument indicates the argument will be retrieved from the model.If not present in the model, the argument will be instantiated first and then added to the model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文