Was ist @ModelAttribute in Spring MVC?

372

Was ist der Zweck und die Verwendung @ModelAttributein Spring MVC?

Mohammad Adnan
quelle
40
Ich denke, dies ist eine nützliche Frage, da die Leser mehr Informationen (einschließlich Beispiele) erhalten können, als die offizielle Spring-Dokumentation bietet.
anton1980
3
Überprüfen Sie diesen Artikel hier. thespringthing.blogspot.com/2010/11/…
praveenj

Antworten:

399

@ModelAttributeverweist auf eine Eigenschaft des Model-Objekts (das M in MVC;). Nehmen wir also an, wir haben ein Formular mit einem Formular-Backing-Objekt namens "Person". Dann kann Spring MVC dieses Objekt mithilfe der @ModelAttributeAnnotation einer Controller-Methode bereitstellen ::

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

Andererseits wird die Annotation verwendet, um Objekte zu definieren, die Teil eines Modells sein sollen. Wenn Sie also möchten, dass ein Personenobjekt im Modell referenziert wird, können Sie die folgende Methode verwenden:

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

Diese mit Anmerkungen versehene Methode ermöglicht den Zugriff auf das Personenobjekt in Ihrer Ansicht, da es bis zum Frühjahr automatisch zu den Modellen hinzugefügt wird.

Siehe "Verwenden von @ModelAttribute" .

fasseg
quelle
8
@fasseg Das brauchst du eigentlich nicht @ModelAttributein deinem ersten Fall.
Neil McGuigan
@Neil Wann müssen Sie @ModelAttributein Methodenattributen verwenden?
Ryan
4
@ Ryan siehe stackoverflow.com/questions/8688135/…
Neil McGuigan
1
Sie sollten angeben, wie Person ausgefüllt ist und wie diese Methode aufgerufen wird.
Philip Rego
134

Ich weiß, dass dies ein alter Faden ist, aber ich dachte, ich werfe meinen Hut in den Ring und sehe, ob ich das Wasser ein bisschen mehr trüben kann :)

Ich fand, mein anfänglicher Kampf um das Verständnis @ModelAttributewar das Ergebnis der Entscheidung von Spring, mehrere Anmerkungen zu einer zu kombinieren. Es wurde klarer, als ich es in mehrere kleinere Anmerkungen aufteilte:

Stellen Sie sich bei Parameteranmerkungen @ModelAttributedas Äquivalent von vor, @Autowired + @Qualifierdh es wird versucht, eine Bean mit dem angegebenen Namen aus dem von Spring verwalteten Modell abzurufen. Wenn die benannte Bean nicht gefunden wird, nullübernimmt sie implizit die Rolle von , anstatt einen Fehler auszulösen oder zurückzukehren@Bean dh mithilfe des Standardkonstruktors eine neue Instanz zu erstellen und die Bean dem Modell hinzuzufügen .

Stellen Sie sich bei Methodenanmerkungen @ModelAttributedas Äquivalent von vor @Bean + @Before, dh, die durch den Benutzercode erstellte Bean wird in das Modell eingefügt und immer vor einer Anforderungsbehandlungsmethode aufgerufen.

Im übertragenen Sinne sehe ich @ModelAttributeFolgendes (bitte nicht wörtlich nehmen !!):

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

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

Wie Sie sehen, hat Spring die richtige Entscheidung getroffen, @ModelAttributeeine umfassende Anmerkung zu machen . niemand will ein annotation smorgasbord sehen.

Christopher Yang
quelle
2
Hm, @Bean ist standardmäßig Singleton. Ich bin mir nicht sicher, ob hier dieselben Konzepte gelten.
Zombies
10
Absolut nicht. Ich verwende nur einfachere Anmerkungen, um diese komplexe Anmerkung zu erklären. Bitte nehmen Sie meine Erklärung konzeptionell und nicht wörtlich.
Christopher Yang
4
@ Zombies @Scope("request")dann hinzufügen :)
OrangeDog
28

Für meinen Stil verwende ich immer @ModelAttribute, um Objekte aus der Frühlingsform jsp zu fangen. Zum Beispiel entwerfe ich ein Formular auf einer JSP-Seite. Dieses Formular existiert mit commandName

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

und ich fange das Objekt auf dem Controller mit folgendem Code

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

und jeder Feldname des Buches muss mit dem Pfad im Unterelement der Form übereinstimmen

Leang Socheat
quelle
4
Das catchVerb beschreibt genau die geleistete @ModelAttributeArbeit. Nett.
Eddy
3
Beste Antwort des Jahres.
Jupiter Cls
4
Aber ist es notwendig? Dies funktioniert immer noch ohne Verwendung der Annotation @ModelAttribute.
23

Also werde ich versuchen, es einfacher zu erklären. Lass uns:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

Wie in der Spring MVC-Dokumentation beschrieben, kann die Annotation @ModelAttribute für Methoden oder Methodenargumente verwendet werden . Und natürlich können wir beide gleichzeitig in einem Controller verwenden.

1.Methodenanmerkung

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

Zweck einer solchen Methode ist das Hinzufügen von Attributen im Modell. Also in unserem Fall Städte Schlüssel wird die Liste haben new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})als Wert im Modell (kann man sich vorstellen Modell als Karte (key: value)). @ ModelAttribute- Methoden in einem Controller werden vor @ RequestMapping- Methoden innerhalb desselben Controllers aufgerufen .

Hier möchten wir dem Modell allgemeine Informationen hinzufügen, die im Formular zur Anzeige für den Benutzer verwendet werden. Zum Beispiel kann es verwendet werden, um eine HTML-Auswahl zu füllen:

Geben Sie hier die Bildbeschreibung ein

2.Methodenargument

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

Ein @ModelAttribute für ein Methodenargument gibt an, dass das Argument aus dem Modell abgerufen werden soll. In diesem Fall erwarten wir also, dass wir das Model person- Objekt als Schlüssel haben, und wir möchten seinen Wert abrufen und ihn in das Methodenargument Person person setzen . Wenn dies nicht vorhanden ist oder (manchmal schreiben Sie das (value = "persson") falsch), findet Spring es nicht im Modell und erstellt ein leeres Personenobjekt mit seinen Standardeinstellungen. Nehmen Sie dann die Anforderungsparameter und versuchen Sie, sie mit ihren Namen im Personenobjekt zu binden.

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

Wir haben also einen Namen, der mit setName (String name) an Person.name gebunden wird. Also rein

//..Some logic with person

Wir haben Zugriff auf diesen gefüllten Namen mit dem Wert "Dimitrij".

Natürlich kann Spring komplexere Objekte wie Listen, Karten, Listen von Kartensätzen usw. binden, aber hinter den Kulissen macht es die Datenbindung magisch.

  1. Wir können gleichzeitig eine mit einem Modell versehene Methode und einen Anforderungsmethodenhandler mit @ModelAttribute in den Argumenten haben. Dann müssen wir die Regeln vereinen.

  2. Natürlich gibt es unzählige verschiedene Situationen - @ ModelAttribute-Methoden können auch in einem @ ControlAdvice definiert werden und so weiter ...

Xelian
quelle
13

Ich weiß, dass ich zu spät zur Party komme, aber ich zitiere, wie sie sagen: "Besser zu spät als nie". Also lasst uns loslegen. Jeder hat seine eigenen Möglichkeiten, Dinge zu erklären. Lassen Sie mich versuchen, es in wenigen Schritten mit einem Beispiel für Sie zusammenzufassen und zu vereinfachen. Angenommen, Sie haben ein einfaches Formular, 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" Dies sind die Felder / Eigenschaften in der StudentClass, wenn das Formular aufgerufen wird. Ihre Getter werden aufgerufen. Sobald sie gesendet wurden, werden ihre Setter aufgerufen und ihre Werte werden in der Bean festgelegt, die im modelAttribute = angegeben wurde "Student" im Formular-Tag.

Wir haben StudentController, der die folgenden Methoden enthält;

@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 

jetzt haben wir endlich eine form-details.jsp

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

Zurück zur Frage Was ist @ModelAttribute in Spring MVC? Eine Beispieldefinition aus der Quelle für Sie, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation Das @ModelAttribute ist eine Annotation, die einen Methodenparameter oder einen Methodenrückgabewert an ein benanntes Modellattribut bindet und setzt es dann einer Webansicht aus.

Was tatsächlich passiert, ist, dass alle Werte Ihres Formulars abgerufen werden, die von ihm übermittelt wurden, und diese dann gespeichert werden, damit Sie sie binden oder dem Objekt zuweisen können. Es funktioniert genauso wie der @RequestParameter, bei dem wir nur einen Parameter erhalten und den Wert einem Feld zuweisen. Der einzige Unterschied besteht darin, dass @ModelAttribute alle Formulardaten und nicht nur einen einzelnen Parameter enthält. Es erstellt eine Bean für Sie, die vom Formular übermittelte Daten enthält, die später vom Entwickler verwendet werden sollen.

Um das Ganze noch einmal zusammenzufassen. Schritt 1: Eine Anfrage wird gesendet und unsere Methode showForm wird ausgeführt und ein Modell, eine temporäre Bean mit dem Namen student, wird an das Formular weitergeleitet. theModel.addAttribute ("student", neuer Student ());

Schritt 2: modelAttribute = "student" im Formularübermittlungsmodell ändert den Schüler und enthält nun alle Parameter des Formulars

Schritt 3: @ModelAttribute ("student") Student theStudent Wir rufen die Werte ab, die von @ModelAttribute gehalten werden, und weisen Student die gesamte Bean / das gesamte Objekt zu.

Schritt 4: Und dann verwenden wir es, während wir bieten, genauso wie wir es auf der Seite usw. zeigen, wie ich es getan habe

Ich hoffe, es hilft Ihnen, das Konzept zu verstehen. Vielen Dank

Majid Ali Khan
quelle
9

Nehmen Sie eine Webanwendung, egal ob es sich um Google Mail, Facebook, Instagram oder eine andere Webanwendung handelt. Es geht um den Austausch von Daten oder Informationen zwischen dem Endbenutzer und der Anwendung oder der Benutzeroberfläche und der Back-End-Anwendung. Selbst in der MVC-Welt im Frühjahr gibt es zwei Möglichkeiten, Daten auszutauschen:

  1. vom Controller zur Benutzeroberfläche und
  2. von der Benutzeroberfläche zum Controller.

Was uns hier interessiert, ist, wie die Daten von der Benutzeroberfläche an den Controller übertragen werden. Dies kann auch auf zwei Arten erfolgen:

  1. Verwenden eines HTML-Formulars
  2. Abfrageparameter verwenden.

Verwenden eines HTML-Formulars: Betrachten Sie das folgende Szenario:

Form Submission Representation

Wenn wir die Formulardaten über den Webbrowser senden, können wir als Objekt auf diese Daten in unserer Controller-Klasse zugreifen. Wenn wir ein HTML-Formular senden, führt der Spring Container vier Dinge aus. Es wird,

  1. Lesen Sie zuerst alle Daten, die in der Anforderung übermittelt werden, mit der Methode request.getParameter .
  2. Sobald sie gelesen wurden, werden sie mit integer.parseInt , double.parseDouble und allen anderen verfügbaren Analysemethoden, die basierend auf dem Datentyp der Daten verfügbar sind , in den entsprechenden Java-Typ konvertiert .
  3. Nach dem Analysieren wird ein Objekt der von uns erstellten Modellklasse erstellt. In diesem Szenario werden beispielsweise die Benutzerinformationen gesendet, und wir erstellen eine Klasse namens Benutzer, von der der Container ein Objekt erstellt und alle Werte festlegt, die automatisch in dieses Objekt eingehen.
  4. Das Objekt wird dann übergeben, indem die Werte auf den Controller gesetzt werden.

Damit das Ganze funktioniert, müssen wir bestimmte Schritte ausführen.

Interne Arbeit

Wir müssen zuerst eine Modellklasse wie User definieren, in der die Anzahl der Felder genau mit der Anzahl der Felder im HTML-Formular übereinstimmen soll. Außerdem sollten die Namen, die wir im HTML-Formular verwenden, mit den Namen übereinstimmen, die wir in der Java-Klasse haben. Diese beiden sind sehr wichtig. Namen sollten übereinstimmen, die Anzahl der Felder im Formular sollte mit der Anzahl der Felder in der von uns erstellten Klasse übereinstimmen. Sobald wir dies tun, liest der Container automatisch die eingehenden Daten, erstellt ein Objekt dieses Modells, legt die Werte fest und übergibt es dem Controller. Um diese Werte im Controller zu lesen, verwenden wir das @ModelAttributeAnmerkung zu den Methodenparametern. Wenn wir Methoden im Controller erstellen, verwenden wir das @ModelAttribute und fügen einen Parameter hinzu, der dieses Objekt automatisch vom Container angibt.

Hier ist ein Beispielcode zum Registrieren eines Benutzers:

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

Hoffe diese schematische Erklärung hat geholfen!

Nithin Prasad
quelle
4

Dies wird im Frühjahr für Datenbindungszwecke verwendet MVC. Lassen Sie einen JSP mit einem Formularelement haben, z

auf JSP

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

(Spring Form-Methode, einfaches Formularelement kann ebenfalls verwendet werden)

Auf der Controllerseite

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

}

Wenn Sie nun das Formular senden, stehen Ihnen die Werte der Formularfelder zur Verfügung.

Awais
quelle
4

Anmerkung, die einen Methodenparameter oder einen Methodenrückgabewert an ein benanntes Modellattribut bindet, das einer Webansicht zur Verfügung gestellt wird.

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

@ModelAttribute kann als Methodenargument / -parameter oder vor der Methodendeklaration verwendet werden. Das Hauptziel dieser Anmerkung besteht darin, die Anforderungsparameter oder Formularfelder an ein Modellobjekt zu binden

Ref. http://www.javabeat.net/modelattribute-spring-mvc/

Chethan D.
quelle
1

@ModelAttributeerstellt ein Attribut mit dem Namen, den Sie (@ModelAttribute("Testing") Test test) as Testing im angegebenen Beispiel angegeben haben. Test ist der Bean-Test, der die Referenz auf die Bean darstellt, und Testing ist im Modell verfügbar, sodass Sie es auf JSP-Seiten zum Abrufen der von Ihnen gespeicherten Werte weiter verwenden können in dir ModelAttribute.

Gagan
quelle
1

@ModelAttribute bindet einfach den Wert aus JSP-Feldern an Pojo-Calss, um unsere Logik in der Controller-Klasse auszuführen. Wenn Sie mit Streben vertraut sind, entspricht dies dem Auffüllen des formbean-Objekts beim Senden.

Ragu Venkatesan
quelle
0

Die ModelAttribute-Annotation wird als Teil einer Spring MVC-Webanwendung verwendet und kann in zwei Szenarien verwendet werden.

Erstens kann es verwendet werden, um Daten in ein Pre-JSP-Lademodell einzufügen. Dies ist besonders nützlich, um sicherzustellen, dass eine JSP erforderlich ist, um alle Daten selbst anzuzeigen. Eine Injektion wird erhalten, indem eine Methode mit dem Modell verbunden wird.

Zweitens können damit Daten aus einem vorhandenen Modell gelesen und den Parametern der Coach-Methode zugewiesen werden.

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

Ismael
quelle
0

Auf Methodenebene

1.Wenn die Annotation auf Methodenebene verwendet wird, gibt sie an, dass der Zweck dieser Methode darin besteht, ein oder mehrere Modellattribute hinzuzufügen

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

Beim Methodenargument 1. Wenn es als Methodenargument verwendet wird, gibt es an, dass das Argument aus dem Modell abgerufen werden soll. Wenn sie nicht vorhanden sind und zuerst instanziiert und dann zum Modell hinzugefügt werden sollen und sobald sie im Modell vorhanden sind, sollten die Argumentfelder aus allen Anforderungsparametern mit übereinstimmenden Namen ausgefüllt werden. Daher werden die Formulardaten mit einer Bean verknüpft.

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