2011-12-31 25 views
31

digamos que tenemos una entidad persona, un controlador PersonController y una página edit.jsp (la creación de una nueva edición de una persona o existente)@ModelAttribute anotación, ¿cuándo usarlo?

controlador

@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> 

Estoy intentando el código anterior (sin utilizar la anotación @ModelAttribute en el método savePerson, y funciona correctamente. Por qué y cuándo debo agregar la anotación al objeto persona:

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

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

Respuesta

2

Su pregunta parece ser contestado ya:

What is @ModelAttribute in Spring MVC?

para resumir el mensaje de respuesta y el blog: cuando se desea que el objeto formulario de respaldo (instancia de la persona), que se mantuvo a través de solicitudes.

De lo contrario, sin la anotación, el método mapeado de solicitud asumirá que Persona es un objeto nuevo y de ninguna manera está vinculado a su objeto de respaldo de formulario. La publicación de blog que el póster hace referencia es realmente impresionante, definitivamente una lectura obligada.

+0

... pero los valores en el modelo no se mantienen entre las solicitudes a menos que esté utilizando RedirectAttributesModelMap? ¿en eso? – dade

51

No es necesario @ModelAttribute (parámetro) sólo para usar un Bean como un parámetro

Por ejemplo, estos métodos de controlador funcionan bien con estas peticiones:

@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 

Uso @ModelAttribute (método) para cargar datos predeterminados en su modelo en cada solicitud - para examen de una base de datos, especialmente cuando usa @SessionAttributes.Esto se puede hacer en un Controller o en un ControllerAdvice:

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

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

} 

Cualquier JSP remitida al por FooController:

${foo} //=bar 

o

@ControllerAdvice 
public class MyGlobalData { 

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

} 

Cualquier JSP:

${foo} //=bar 

Uso @ModelAttribute (parámetro) si desea utilizar el resultado de @ModelAttribute (método) como un defecto :

@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 

Uso @ModelAttribute (parámetro) para obtener un objeto almacenado en un flash atributo:

@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 

Uso @ModelAttribute (parámetro) para obtener un objeto almacenado por @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 

+0

Cómo usar '@ ModelAttribute' en el método' PUT' – viper

+1

Just Wow. Tan útil –

+0

¿Cómo establecería los valores predeterminados para @ModelAttribute cuando lo usa como parámetro? Ej: (@RequestParam (value = "studentName", defaultValue = "Alexa") – Jesse

0

Un @ModelAttribute en un argumento método indica el argumento se recuperará a partir del modelo. Si no está presente en el modelo, primero se creará una instancia del argumento y luego se agregará al modelo.

Cuestiones relacionadas