Qu'est-ce que @ModelAttribute dans Spring MVC?

372

Quel est le but et l'utilisation de @ModelAttributeSpring MVC?

Mohammad Adnan
la source
40
Je pense que c'est une question utile, car elle permet aux lecteurs d'obtenir plus d'informations (y compris des exemples) que la documentation officielle de Spring ne fournit.
anton1980
3
Consultez cet article ici. thespringthing.blogspot.com/2010/11/…
praveenj

Réponses:

399

@ModelAttributefait référence à une propriété de l'objet Model (le M dans MVC;) alors disons que nous avons un formulaire avec un objet de support de formulaire qui est appelé "Personne". Ensuite, vous pouvez demander à Spring MVC de fournir cet objet à une méthode Controller en utilisant l' @ModelAttributeannotation :

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

D'autre part, l'annotation est utilisée pour définir des objets qui doivent faire partie d'un modèle. Donc, si vous voulez avoir un objet Person référencé dans le modèle, vous pouvez utiliser la méthode suivante:

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

Cette méthode annotée permettra d'accéder à l'objet Personne dans votre vue, car il est automatiquement ajouté aux modèles par Spring.

Voir "Utilisation de @ModelAttribute" .

faitg
la source
8
@fasseg Vous n'avez pas réellement besoin @ModelAttributede votre premier cas.
Neil McGuigan
@Neil Quand devez-vous utiliser des @ModelAttributeattributs de méthode?
Ryan
4
@Ryan voir stackoverflow.com/questions/8688135/…
Neil McGuigan
1
vous devez indiquer comment Person est renseigné et comment cette méthode est appelée.
Philip Rego
134

Je sais que c'est un vieux fil, mais j'ai pensé jeter mon chapeau dans le ring et voir si je pouvais bouer l'eau un peu plus :)

J'ai trouvé que ma lutte initiale pour comprendre @ModelAttributeétait le résultat de la décision de Spring de combiner plusieurs annotations en une seule. Il est devenu plus clair une fois que je l'ai divisé en plusieurs annotations plus petites:

Pour les annotations de paramètres, pensez @ModelAttributeà l'équivalent de @Autowired + @Qualifierc'est à dire qu'il essaie de récupérer un bean avec le nom donné à partir du modèle géré par Spring. Si le bean nommé n'est pas trouvé, au lieu de lancer une erreur ou de retourner null, il joue implicitement le rôle de @Beanie Créer une nouvelle instance en utilisant le constructeur par défaut et ajouter le bean au modèle.

Pour les annotations de méthode, pensez @ModelAttributeà l'équivalent de @Bean + @Before, c'est-à-dire qu'il place le bean construit par le code de l'utilisateur dans le modèle et il est toujours appelé avant une méthode de traitement des requêtes.

Au sens figuré, je vois @ModelAttributecomme suit (s'il vous plaît ne le prenez pas à la lettre !!):

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

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

Comme vous pouvez le voir, Spring a pris la bonne décision de faire @ModelAttributeune annotation globale; personne ne veut voir un smorgasbord d'annotation.

Christopher Yang
la source
2
Hm, @Bean est singleton par défaut. Je ne suis pas sûr que les mêmes concepts s'appliquent ici.
Zombies
10
Absolument pas. J'utilise simplement des annotations plus simples pour expliquer cette annotation complexe. Veuillez prendre mon explication conceptuellement, pas littéralement.
Christopher Yang
4
@Zombies ajoute @Scope("request")alors :)
OrangeDog
28

Pour mon style, j'utilise toujours @ModelAttribute pour attraper un objet à partir de jsp de forme de ressort. par exemple, je conçois un formulaire sur une page jsp, ce formulaire existe avec commandName

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

et j'attrape l'objet sur le contrôleur avec le code de suivi

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

et chaque nom de champ du livre doit correspondre au chemin dans le sous-élément du formulaire

Leang Socheat
la source
4
Le catchverbe décrit exactement le travail @ModelAttributeaccompli. Agréable.
Eddy
3
Meilleure réponse de l'année.
Jupiter Cls
4
Mais est-ce nécessaire? Cela fonctionne toujours sans utiliser l'annotation @ModelAttribute.
23

Je vais donc essayer de l'expliquer de manière plus simple. Ayons:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

Comme décrit dans la documentation Spring MVC - l' annotation @ModelAttribute peut être utilisée sur des méthodes ou sur des arguments de méthode . Et bien sûr, nous pouvons utiliser les deux en même temps dans un seul contrôleur.

1. annotation de méthode

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

Le but d'une telle méthode est d'ajouter un attribut dans le modèle. Ainsi, dans notre cas , la clé des villes aura la liste new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})comme valeur dans le modèle (vous pouvez considérer le modèle comme une carte (clé: valeur)). Les méthodes @ModelAttribute dans un contrôleur sont appelées avant les méthodes @RequestMapping , dans le même contrôleur.

Ici, nous voulons ajouter au modèle des informations communes qui seront utilisées dans le formulaire à afficher pour l'utilisateur. Par exemple, il peut être utilisé pour remplir une sélection HTML:

entrez la description de l'image ici

2. argument de méthode

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

Un @ModelAttribute sur un argument de méthode indique que l'argument doit être extrait du modèle. Ainsi, dans ce cas, nous nous attendons à ce que nous ayons dans l' objet Personne modèle comme clé et nous voulons obtenir sa valeur et la mettre dans l'argument de méthode Personne personne . Si cela n'existe pas (ou parfois vous mal orthographiez le (valeur = "persson")), Spring ne le trouvera pas dans le modèle et créera un objet Personne vide en utilisant ses valeurs par défaut. Ensuite, prendra les paramètres de demande et essaiera de les lier aux données dans l'objet Person en utilisant leurs noms.

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

Nous avons donc un nom et il sera lié à Person.name en utilisant setName (String name). Donc dans

//..Some logic with person

nous avons accès à ce nom rempli avec la valeur "Dimitrij".

Bien sûr, Spring peut lier des objets plus complexes comme des listes, des cartes, une liste d'ensembles de cartes, etc., mais derrière la scène, il rend la liaison de données magique.

  1. Nous pouvons avoir en même temps une méthode annotée de modèle et un gestionnaire de méthode de requête avec @ModelAttribute dans les arguments. Ensuite, nous devons unir les règles.

  2. Bien sûr, nous avons des tonnes de situations différentes - les méthodes @ModelAttribute peuvent également être définies dans un @ControllerAdvice et ainsi de suite ...

Xelian
la source
13

Je sais que je suis en retard à la fête, mais je citerai comme on dit, "il vaut mieux être en retard que jamais". Alors allons-y, Tout le monde a sa propre façon d'expliquer les choses, permettez-moi d'essayer de le résumer et de le simplifier pour vous en quelques étapes avec un exemple; Supposons que vous ayez un formulaire 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" Ce sont les champs / propriétés dans StudentClass lorsque le formulaire est appelé, leurs getters sont appelés mais une fois soumis, leurs setters sont appelés et leurs valeurs sont définies dans le bean qui a été indiqué dans le modelAttribute = "étudiant" dans la balise de formulaire.

Nous avons StudentController qui inclut les méthodes suivantes;

@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 

maintenant nous avons enfin un formulaire-details.jsp

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

Revenons donc à la question Qu'est-ce que @ModelAttribute dans Spring MVC? Une définition de l' échantillon de la source pour vous, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation Le @ModelAttribute est une annotation qui lie un paramètre de méthode ou de la valeur de retour de la méthode à un attribut de modèle nommé puis l'expose à une vue Web.

Ce qui se passe réellement, c'est qu'il obtient toutes les valeurs de votre formulaire qui ont été soumises par lui, puis les conserve pour que vous puissiez les lier ou les affecter à l'objet. Il fonctionne de la même manière que @RequestParameter où nous obtenons uniquement un paramètre et assignons la valeur à un champ. La seule différence est que @ModelAttribute contient toutes les données du formulaire plutôt qu'un seul paramètre. Il crée pour vous un bean qui contient les données soumises sous forme à utiliser par le développeur ultérieurement.

Pour récapituler le tout. Étape 1: Une demande est envoyée et notre méthode showForm s'exécute et un modèle, un bean temporaire est défini avec le nom student est transmis au formulaire. theModel.addAttribute ("étudiant", nouvel étudiant ());

Étape 2: modelAttribute = "student" sur le modèle de soumission de formulaire change l'étudiant et maintenant il contient tous les paramètres du formulaire

Étape 3: @ModelAttribute ("étudiant") Student theStudent Nous récupérons les valeurs détenues par @ModelAttribute et assignons le bean / objet entier à Student.

Étape 4: Et puis nous l'utilisons comme nous enchérissons, tout comme le montrer sur la page, etc.

J'espère que cela vous aide à comprendre le concept. Merci

Majid Ali Khan
la source
9

Prenez n'importe quelle application Web, que ce soit Gmail, Facebook ou Instagram ou toute autre application Web, il s'agit d'échanger des données ou des informations entre l'utilisateur final et l'application ou l'interface utilisateur et l'application principale. Même dans le monde Spring MVC, il existe deux façons d'échanger des données:

  1. du contrôleur à l'interface utilisateur, et
  2. de l'interface utilisateur au contrôleur.

Ce qui nous intéresse ici, c'est comment les données sont communiquées de l'interface utilisateur au contrôleur. Cela peut également se faire de 2 manières:

  1. Utilisation d'un formulaire HTML
  2. Utilisation des paramètres de requête.

Utilisation d'un formulaire HTML: considérez le scénario ci-dessous,

Représentation de soumission de formulaire

Lorsque nous soumettons les données du formulaire à partir du navigateur Web, nous pouvons accéder à ces données dans notre classe Controller en tant qu'objet. Lorsque nous soumettons un formulaire HTML, le conteneur Spring fait quatre choses. Ce sera,

  1. lisez d'abord toutes les données soumises qui viennent dans la demande en utilisant la méthode request.getParameter .
  2. une fois qu'il les lit, il les convertit dans le type Java approprié à l' aide Integer.parseInt , Double.parseDouble et toutes les autres méthodes d'analyse grammaticale qui sont disponibles en fonction du type de données des données.
  3. une fois analysé, il créera un objet de la classe modèle que nous avons créée. Par exemple, dans ce scénario, ce sont les informations utilisateur qui sont soumises et nous créons une classe appelée User, dont le conteneur créera un objet et définira toutes les valeurs qui entrent automatiquement dans cet objet.
  4. il transférera ensuite cet objet en définissant les valeurs sur le contrôleur.

Pour que tout cela fonctionne, nous devrons suivre certaines étapes.

Travail interne

Nous devons d'abord définir une classe de modèle, comme User, dans laquelle le nombre de champs doit correspondre exactement au nombre de champs dans le formulaire HTML. De plus, les noms que nous utilisons dans le formulaire HTML doivent correspondre aux noms que nous avons dans la classe Java. Ces deux sont très importants. Les noms doivent correspondre, le nombre de champs du formulaire doit correspondre au nombre de champs de la classe que nous créons. Une fois que nous faisons cela, le conteneur lira automatiquement les données qui arrivent, crée un objet de ce modèle, définit les valeurs et le transmet au contrôleur. Pour lire ces valeurs à l'intérieur du contrôleur, nous utilisons @ModelAttributeannotation sur les paramètres de la méthode. Lorsque nous créons des méthodes dans le Controller, nous allons utiliser @ModelAttribute et y ajouter un paramètre qui aura automatiquement cet objet donné par le Container.

Voici un exemple de code pour enregistrer un utilisateur:

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

J'espère que cette explication schématique a aidé!

Nithin Prasad
la source
4

Ceci est utilisé à des fins de liaison de données au printemps MVC. Laissez-vous avoir un jsp contenant un élément de formulaire par exemple

sur JSP

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

(Méthode Spring Form, un élément de formulaire simple peut également être utilisé)

Côté contrôleur

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

}

Maintenant, lorsque vous soumettrez le formulaire, les valeurs des champs du formulaire seront disponibles.

Awais
la source
4

Annotation qui lie un paramètre de méthode ou une valeur de retour de méthode à un attribut de modèle nommé, exposé à une vue Web.

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

@ModelAttribute peut être utilisé comme argument / paramètre de méthode ou avant la déclaration de méthode. L'objectif principal de cette annotation est de lier les paramètres de demande ou les champs de formulaire à un objet de modèle

Réf. http://www.javabeat.net/modelattribute-spring-mvc/

Chethan D
la source
1

@ModelAttributecréera un attribut avec le nom que vous avez spécifié (@ModelAttribute("Testing") Test test) as Testing dans l'exemple donné, Test étant le test du bean étant la référence au bean et Testing sera disponible dans le modèle afin que vous puissiez l'utiliser plus loin sur les pages jsp pour récupérer les valeurs que vous avez stockées en toi ModelAttribute.

Gagan
la source
1

@ModelAttribute lie simplement la valeur des champs jsp aux cals Pojo pour exécuter notre logique dans la classe du contrôleur. Si vous connaissez les struts, cela revient à remplir l'objet formbean lors de la soumission.

Ragu Venkatesan
la source
0

L'annotation ModelAttribute est utilisée dans le cadre d'une application Web Spring MVC et peut être utilisée dans deux scénarios.

Tout d'abord, il peut être utilisé pour injecter des données dans un modèle de charge pré-JSP. Ceci est particulièrement utile pour garantir qu'un JSP est requis pour afficher toutes les données lui-même. Une injection est obtenue en connectant une méthode au modèle.

Deuxièmement, il peut être utilisé pour lire les données d'un modèle existant et les affecter aux paramètres de la méthode du coach.

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

ismael
la source
0

Au niveau de la méthode

1.Lorsque l'annotation est utilisée au niveau de la méthode, elle indique que le but de cette méthode est d'ajouter un ou plusieurs attributs de modèle

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

Au niveau de l'argument de méthode 1. Lorsqu'il est utilisé comme argument de méthode, il indique que l'argument doit être extrait du modèle. Lorsqu'ils ne sont pas présents et doivent d'abord être instanciés puis ajoutés au modèle et une fois présents dans le modèle, les champs d'arguments doivent être remplis à partir de tous les paramètres de demande qui ont des noms correspondants. Ainsi, il lie les données du formulaire avec un bean.

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