¿Qué es @ModelAttribute en Spring MVC?

372

¿Cuál es el propósito y el uso de @ModelAttributeSpring MVC?

Mohammad Adnan
fuente
40
Creo que esta es una pregunta útil, ya que permite a los lectores obtener más información (incluidos ejemplos) que la que proporciona la documentación oficial de Spring.
anton1980
3
Mira este artículo aquí. thespringthing.blogspot.com/2010/11/…
praveenj

Respuestas:

399

@ModelAttributese refiere a una propiedad del objeto Modelo (la M en MVC;) así que digamos que tenemos un formulario con un objeto de respaldo de formulario que se llama "Persona". Luego puede hacer que Spring MVC suministre este objeto a un método Controlador utilizando la @ModelAttributeanotación :

public String processForm(@ModelAttribute("person") Person person){
    person.getStuff();
}

Por otro lado, la anotación se usa para definir objetos que deberían ser parte de un Modelo. Entonces, si desea que se haga referencia a un objeto Persona en el Modelo, puede usar el siguiente método:

@ModelAttribute("person")
public Person getPerson(){
    return new Person();
}

Este método anotado permitirá el acceso al objeto Persona en su Vista, ya que Spring lo agrega automáticamente a los Modelos.

Consulte "Uso de @ModelAttribute" .

Fasseg
fuente
8
@fasseg En realidad no necesitas @ModelAttributeen tu primer caso.
Neil McGuigan
@Neil ¿Cuándo necesita usar los @ModelAttributeatributos del método?
Ryan
44
@ Ryan ver stackoverflow.com/questions/8688135/…
Neil McGuigan
1
debe incluir cómo se rellena Person y cómo se llama a este método.
Philip Rego el
134

Sé que este es un hilo viejo, pero pensé en tirar mi sombrero en el ring y ver si puedo enturbiar el agua un poco más :)

Descubrí que mi lucha inicial por comprender @ModelAttributeera el resultado de la decisión de Spring de combinar varias anotaciones en una. Se hizo más claro una vez que lo dividí en varias anotaciones más pequeñas:

Para las anotaciones de parámetros, piense que @ModelAttributees el equivalente de, @Autowired + @Qualifieres decir, que intenta recuperar un bean con el nombre del modelo administrado por Spring. Si no se encuentra el bean con nombre, en lugar de arrojar un error o regresar null, implícitamente asume el rol de, por @Beanejemplo, crear una nueva instancia utilizando el constructor predeterminado y agregar el bean al modelo.

Para las anotaciones de métodos, piense @ModelAttributeen el equivalente de @Bean + @Before, es decir, coloca el bean construido por el código del usuario en el modelo y siempre se llama antes que un método de manejo de solicitudes.

Figurativamente, veo @ModelAttributelo siguiente (¡por favor, no lo tomes literalmente!):

@Bean("person")
@Before
public Person createPerson(){
  return new Person();
}

@RequestMapping(...)
public xxx handlePersonRequest( (@Autowired @Qualifier("person") | @Bean("person")) Person person, xxx){
  ...
}

Como puede ver, Spring tomó la decisión correcta de hacer @ModelAttributeuna anotación global; nadie quiere ver una anotación smorgasbord.

Christopher Yang
fuente
2
Hm, @Bean es singleton por defecto. No estoy seguro de que los mismos conceptos se apliquen aquí.
Zombies
10
Absolutamente no. Solo estoy usando anotaciones más simples para explicar esta compleja anotación. Por favor tome mi explicación conceptualmente, no literalmente.
Christopher Yang
44
@Zombies add @Scope("request")then :)
OrangeDog
28

Para mi estilo, siempre uso @ModelAttribute para capturar objetos de spring form jsp. por ejemplo, diseño un formulario en la página jsp, ese formulario existe con commandName

<form:form commandName="Book" action="" methon="post">
      <form:input type="text" path="title"></form:input>
</form:form>

y atrapo el objeto en el controlador con el siguiente código

public String controllerPost(@ModelAttribute("Book") Book book)

y cada nombre de campo del libro debe coincidir con la ruta en el subelemento de forma

Leang Socheat
fuente
44
El catchverbo describe exactamente el trabajo que @ModelAttributeha realizado. Agradable.
Eddy
3
La mejor respuesta del año.
Jupiter Cls
44
¿Pero es necesario? Esto sigue funcionando sin usar la anotación @ModelAttribute.
23

Así que intentaré explicarlo de una manera más simple. Tengamos:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}

Como se describe en la documentación de Spring MVC, la anotación @ModelAttribute se puede usar en métodos o en argumentos de métodos . Y, por supuesto, podemos tener ambos usos al mismo tiempo en un controlador.

1. Anotación de método

@ModelAttribute(“cities”)
 public List<String> checkOptions(){
 return new Arrays.asList(new[]{“Sofia”,”Pleven","Ruse”});//and so on
}

El propósito de dicho método es agregar un atributo en el modelo. Entonces, en nuestro caso, la clave de ciudades tendrá la lista new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})como valor en el Modelo (puede pensar en el Modelo como un mapa (clave: valor)). Los métodos @ModelAttribute en un controlador se invocan antes que los métodos @RequestMapping , dentro del mismo controlador.

Aquí queremos agregar al modelo información común que se utilizará en el formulario para mostrar al usuario. Por ejemplo, se puede usar para completar una selección HTML:

ingrese la descripción de la imagen aquí

2 argumento del método

public String findPerson(@ModelAttriute(value="person") Person person) {
    //..Some logic with person
    return "person.jsp";
}

Un @ModelAttribute en un argumento de método indica que el argumento debe recuperarse del modelo. Entonces, en este caso, esperamos tener el objeto Persona modelo como clave y queremos obtener su valor y ponerlo en el argumento del método Persona persona . Si no existe o (a veces escribe mal el (valor = "persson")) entonces Spring no lo encontrará en el Modelo y creará un objeto Persona vacío usando sus valores predeterminados. Luego tomará los parámetros de la solicitud e intentará vincularlos en el objeto Persona con sus nombres.

name="Dmitrij"&countries=Lesoto&sponsor.organization="SilkRoad"&authorizedFunds=&authorizedHours=&

Entonces tenemos nombre y se unirá a Person.name usando setName (String name). Entonces en

//..Some logic with person

tenemos acceso a este nombre con el valor "Dimitrij".

Por supuesto, Spring puede unir objetos más complejos como Listas, Mapas, Lista de conjuntos de mapas, etc., pero detrás de la escena hace que los datos sean mágicos.

  1. Al mismo tiempo, podemos tener un modelo de método anotado y un controlador de método de solicitud con @ModelAttribute en los argumentos. Luego tenemos que unir las reglas.

  2. Por supuesto, tenemos toneladas de situaciones diferentes: los métodos @ModelAttribute también se pueden definir en un @ControllerAdvice y así sucesivamente ...

Xelian
fuente
13

Sé que llego tarde a la fiesta, pero citaré como dicen, "mejor llegar tarde que nunca". Así que comencemos, todos tienen sus propias formas de explicar las cosas, déjenme tratar de resumirlo y simplificarlo en unos pocos pasos con un ejemplo; Supongamos que tiene una forma simple, form.jsp

<form:form action="processForm" modelAttribute="student">
First Name : <form:input path="firstName" /> 
<br><br>
Last Name : <form:input path="lastName" />
<br><br>
<input type="submit" value="submit"/>
</form:form>

path = "firstName" path = "lastName" Estos son los campos / propiedades en la clase de estudiantes cuando se llama al formulario, se llaman sus captadores, pero una vez enviados, se llaman sus setters y sus valores se establecen en el bean que se indicó en modelAttribute = "estudiante" en la etiqueta del formulario.

Tenemos StudentController que incluye los siguientes métodos;

@RequestMapping("/showForm")
public String showForm(Model theModel){ //Model is used to pass data between 
//controllers and views
    theModel.addAttribute("student", new Student()); //attribute name, value
return "form";
}

@RequestMapping("/processForm")
public String processForm(@ModelAttribute("student") Student theStudent){
    System.out.println("theStudent :"+ theStudent.getLastName());
return "form-details";
}

//@ModelAttribute("student") Student theStudent
//Spring automatically populates the object data with form data all behind the 
//scenes 

ahora finalmente tenemos un formulario-details.jsp

<b>Student Information</b>
${student.firstName}
${student.lastName}

Volvamos a la pregunta ¿Qué es @ModelAttribute en Spring MVC? Una definición de ejemplo de la fuente para usted, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation El @ModelAttribute es una anotación que se une un parámetro de método o el valor de retorno del método a un atributo llamado modelo y luego lo expone a una vista web.

Lo que realmente sucede es que obtiene todos los valores de su formulario que fueron enviados por él y luego los guarda para que pueda vincularlos o asignarlos al objeto. Funciona igual que el @RequestParameter donde solo obtenemos un parámetro y asignamos el valor a algún campo. La única diferencia es que @ModelAttribute contiene todos los datos del formulario en lugar de un solo parámetro. Crea un bean para usted que contiene datos enviados por el formulario para que el desarrollador los use más adelante.

Para recapitular todo el asunto. Paso 1: se envía una solicitud y nuestro método showForm se ejecuta y un modelo, se establece un bean temporal con el nombre de estudiante que se reenvía al formulario. theModel.addAttribute ("estudiante", nuevo Estudiante ());

Paso 2: modelAttribute = "estudiante" en el modelo de envío de formulario cambia al estudiante y ahora contiene todos los parámetros del formulario

Paso 3: @ModelAttribute ("estudiante") Student theStudent Obtenemos los valores retenidos por @ModelAttribute y asignamos todo el bean / objeto a Student.

Paso 4: Y luego lo usamos a medida que ofertamos, al igual que lo mostré en la página, etc.

Espero que te ayude a entender el concepto. Gracias

Majid Ali Khan
fuente
9

Tome cualquier aplicación web, ya sea Gmail o Facebook o Instagram o cualquier otra aplicación web, se trata de intercambiar datos o información entre el usuario final y la aplicación o la interfaz de usuario y la aplicación de fondo. Incluso en el mundo Spring MVC hay dos formas de intercambiar datos:

  1. del controlador a la interfaz de usuario, y
  2. desde la interfaz de usuario al controlador.

Lo que nos interesa aquí es cómo se comunican los datos desde la interfaz de usuario al controlador. Esto también se puede hacer de 2 maneras:

  1. Usando un formulario HTML
  2. Uso de parámetros de consulta.

Uso de un formulario HTML: considere el siguiente escenario,

Representación de envío de formulario

Cuando enviamos los datos del formulario desde el navegador web, podemos acceder a esos datos en nuestra clase Controlador como un objeto. Cuando enviamos un formulario HTML, Spring Container hace cuatro cosas. Va a,

  1. primero lea todos los datos que se envían en la solicitud utilizando el método request.getParameter .
  2. una vez que los lea, los convertirá en el tipo Java apropiado usando integer.parseInt , double.parseDouble y todos los demás métodos de análisis disponibles en función del tipo de datos.
  3. una vez analizado, creará un objeto de la clase de modelo que creamos. Por ejemplo, en este escenario, se está enviando la información del usuario y creamos una clase llamada Usuario, de la cual el Contenedor creará un objeto y establecerá todos los valores que entran automáticamente en ese objeto.
  4. luego entregará ese objeto estableciendo los valores en el controlador.

Para que todo funcione, tendremos que seguir ciertos pasos.

Trabajo interno

Primero tenemos que definir una clase de modelo, como Usuario, en la que el número de campos debe coincidir exactamente con el número de campos en el formulario HTML. Además, los nombres que usamos en el formulario HTML deben coincidir con los nombres que tenemos en la clase Java. Estos dos son muy importantes. Los nombres deben coincidir, el número de campos en el formulario debe coincidir con el número de campos en la clase que creamos. Una vez que lo hagamos, el Contenedor leerá automáticamente los datos que ingresan, creará un objeto de este modelo, establecerá los valores y se los entregará al Controlador. Para leer esos valores dentro del controlador, utilizamos el @ModelAttributeAnotación sobre los parámetros del método. Cuando creamos métodos en el Controlador, vamos a utilizar el @ModelAttribute y le agregaremos un parámetro que automáticamente contendrá este objeto.

Aquí hay un código de ejemplo para registrar un usuario:

@RequestMapping(value = "registerUser", method = RequestMethod.POST)
public String registerUser(@ModelAttribute("user") User user, ModelMap model) {
    model.addAttribute("user", user);
    return "regResult";
}

¡Espero que esta explicación esquemática haya ayudado!

Nithin Prasad
fuente
4

Esto se utiliza para fines de enlace de datos en Spring MVC. Permitirle tener un jsp que tenga un elemento de formulario, p. Ej.

en JSP

<form:form action="test-example" method="POST" commandName="testModelAttribute"> </form:form>

(Método Spring Form, también se puede usar un elemento de formulario simple)

En el lado del controlador

@RequestMapping(value = "/test-example", method = RequestMethod.POST)
public ModelAndView testExample(@ModelAttribute("testModelAttribute") TestModel testModel, Map<String, Object> map,...) {

}

Ahora, cuando envíe el formulario, los valores de los campos del formulario estarán disponibles para usted.

Awais
fuente
4

Anotación que vincula un parámetro de método o valor de retorno de método a un atributo de modelo con nombre, expuesto a una vista web.

public String add(@ModelAttribute("specified") Model model) {
    ...
}
Byeon0gam
fuente
3

@ModelAttribute se puede utilizar como argumento / parámetro del método o antes de la declaración del método. El objetivo principal de esta anotación es vincular los parámetros de solicitud o los campos de formulario a un objeto modelo

Árbitro. http://www.javabeat.net/modelattribute-spring-mvc/

Chethan D
fuente
1

@ModelAttributecreará un atributo con el nombre especificado por usted (@ModelAttribute("Testing") Test test) as Testing en el ejemplo dado, Test es la prueba de bean que es la referencia al bean y Testing estará disponible en el modelo para que pueda usarlo más en las páginas jsp para recuperar los valores que almacenó en ti ModelAttribute.

Gagan
fuente
1

@ModelAttribute simplemente vincula el valor de los campos jsp a Pojo calss para realizar nuestra lógica en la clase de controlador. Si está familiarizado con los puntales, entonces esto es como llenar el objeto formbean al enviarlo.

Ragu Venkatesan
fuente
0

La anotación ModelAttribute se usa como parte de una aplicación web Spring MVC y se puede usar en dos escenarios.

En primer lugar, se puede usar para inyectar datos en un modelo de carga anterior a JSP. Esto es especialmente útil para garantizar que se requiere un JSP para mostrar todos los datos en sí. Se obtiene una inyección conectando un método al modelo.

En segundo lugar, se puede usar para leer datos de un modelo existente y asignarlos a los parámetros del método del entrenador.

referencia https://dzone.com/articles/using-spring-mvc%E2%80%99s

ismael
fuente
0

A nivel de método

1. Cuando la anotación se utiliza a nivel de método, indica que el propósito de ese método es agregar uno o más atributos del modelo

@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("india", "india");
}

En el argumento del método 1. Cuando se usa como argumento del método, indica que el argumento debe recuperarse del modelo. Cuando no está presente y debe instanciarse primero y luego agregarse al modelo y una vez presente en el modelo, los campos de argumentos deben rellenarse a partir de todos los parámetros de solicitud que tengan nombres coincidentes. Por lo tanto, une los datos del formulario con un bean.

 @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
  public String submit(@ModelAttribute("employee") Employee employee) {
  return "employeeView";
  }
Vivek Srivastava
fuente