Co to jest @ModelAttribute w Spring MVC?

372

Jaki jest cel i zastosowanie @ModelAttributew Spring MVC?

Mohammad Adnan
źródło
40
Myślę, że jest to przydatne pytanie, ponieważ pozwala czytelnikom uzyskać więcej informacji (w tym przykładów) niż oficjalna dokumentacja wiosenna.
anton1980,
3
Sprawdź ten opis tutaj. thespringthing.blogspot.com/2010/11/...
praveenj

Odpowiedzi:

399

@ModelAttributeodnosi się do właściwości obiektu Model (M w MVC;), więc powiedzmy, że mamy formularz z obiektem wspierającym formularz o nazwie „Osoba”. Następnie możesz poprosić Spring MVC o dostarczenie tego obiektu do metody Controller za pomocą @ModelAttributeadnotacji :

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

Z drugiej strony adnotacja służy do definiowania obiektów, które powinny być częścią modelu. Jeśli więc chcesz mieć odwołanie do obiektu Person w modelu, możesz użyć następującej metody:

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

Ta metoda z adnotacjami umożliwi dostęp do obiektu Person w twoim widoku, ponieważ zostanie on automatycznie dodany do modeli do wiosny.

Zobacz „Korzystanie z @ModelAttribute” .

fasseg
źródło
8
@fasseg Tak naprawdę nie potrzebujesz @ModelAttributew pierwszym przypadku.
Neil McGuigan,
@Neil Kiedy trzeba używać @ModelAttributeatrybutów metody?
Ryan
4
@Ryan patrz stackoverflow.com/questions/8688135/…
Neil McGuigan
1
powinieneś podać sposób zapełniania Osoby i jak wywoływana jest ta metoda.
Philip Rego,
134

Wiem, że to stara nić, ale pomyślałem, że wrzucam czapkę w pierścień i sprawdzam, czy mogę jeszcze trochę zamoczyć wodę :)

Odkryłem, że moja początkowa trudność w zrozumieniu @ModelAttributebyła wynikiem decyzji Springa, aby połączyć kilka adnotacji w jedną. Stało się wyraźniejsze, gdy podzielę go na kilka mniejszych adnotacji:

W przypadku adnotacji parametrów należy traktować je @ModelAttributejako ekwiwalent, @Autowired + @Qualifiertzn. Próbuje ono pobrać komponent bean o podanej nazwie z modelu zarządzanego przez Spring. Jeśli nazwana fasola nie zostanie znaleziona, zamiast zgłosić błąd lub zwrócić null, domyślnie przyjmuje ona rolę @Beannp. Utwórz nową instancję za pomocą domyślnego konstruktora i dodaj fasolę do modelu.

W przypadku adnotacji metod należy traktować je @ModelAttributejako odpowiednik @Bean + @Before, tzn. Umieszcza komponent bean skonstruowany przez kod użytkownika w modelu i zawsze jest wywoływany przed metodą obsługi żądania.

W przenośni widzę, @ModelAttributeco następuje (proszę nie brać tego dosłownie !!):

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

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

Jak widać, Spring podjął właściwą decyzję, by zrobić @ModelAttributewszechstronną adnotację; nikt nie chce zobaczyć adnotacji smorgasbord.

Christopher Yang
źródło
2
Hm, @Bean jest domyślnie singletonem. Nie jestem pewien, czy mają tu zastosowanie te same pojęcia.
Zombie
10
Absolutnie nie. Używam tylko prostszych adnotacji, aby wyjaśnić tę złożoną adnotację. Proszę przyjąć moje wyjaśnienie pojęciowo, a nie dosłownie.
Christopher Yang,
4
@Zombies dodaj @Scope("request")wtedy :)
OrangeDog
28

W moim stylu zawsze używam @ModelAttribute do przechwytywania obiektu z pliku źródłowego jsp. na przykład projektuję formularz na stronie jsp, który istnieje z komendą name

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

i łapię obiekt na kontrolerze za pomocą kodu follow

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

a każda nazwa pola książki musi być zgodna ze ścieżką w podelementie formy

Leang Socheat
źródło
4
catchCzasownik dokładnie opisuje pracę, która @ModelAttributezostała wykonana. Miły.
Eddy,
3
Najlepsza odpowiedź roku.
Jupiter Cls,
4
Ale czy to konieczne? To nadal działa bez użycia adnotacji @ModelAttribute.
23

Spróbuję to wyjaśnić w prostszy sposób. Miejmy:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

Jak opisano w dokumentacji Spring MVC - adnotacja @ModelAttribute może być używana w przypadku metod lub argumentów metod . I oczywiście możemy używać obu jednocześnie w jednym kontrolerze.

1.Metoda adnotacji

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

Celem takiej metody jest dodanie atrybutu do modelu. Zatem w naszym przypadku klucz miast będzie miał listę new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})jako wartość w Modelu (możesz myśleć o Modelu jako mapie (klucz: wartość)). Metody @ModelAttribute w kontrolerze są wywoływane przed metodami @RequestMapping w tym samym kontrolerze.

W tym miejscu chcemy dodać do modelu wspólne informacje, które zostaną wykorzystane w formularzu do wyświetlenia użytkownikowi. Na przykład można go użyć do wypełnienia zaznaczenia HTML:

wprowadź opis zdjęcia tutaj

2. Argument metoda

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

@ModelAttribute w argumencie metody wskazuje, że argument powinien zostać pobrany z modelu. Zatem w tym przypadku oczekujemy, że mamy w obiekcie Model osoby klucz i chcemy uzyskać jego wartość i umieścić go w argumencie metody Person person . Jeśli takie nie istnieje lub (czasami źle wpisujesz (wartość = „persson”)), Spring nie znajdzie go w Modelu i utworzy pusty obiekt Person przy użyciu swoich ustawień domyślnych. Następnie weźmie parametry żądania i spróbuje powiązać je w obiekcie Person przy użyciu ich nazw.

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

Mamy więc nazwę i zostanie ona przypisana do Person.name przy użyciu setName (nazwa ciągu). Więc w

//..Some logic with person

mamy dostęp do tej wypełnionej nazwy o wartości „Dimitrij”.

Oczywiście Wiosna może wiązać bardziej złożone obiekty, takie jak Listy, Mapy, Listy Zestawów Map i tak dalej, ale za sceną sprawia, że ​​wiązanie danych jest magiczne.

  1. Możemy mieć jednocześnie model z adnotacją metody i procedurę obsługi żądania z @ModelAttribute w argumentach. Następnie musimy ujednolicić zasady.

  2. Oczywiście mamy mnóstwo różnych sytuacji - metody @ModelAttribute można również zdefiniować w @AdrollerAdvice i tak dalej ...

Xelian
źródło
13

Wiem, że jestem spóźniony na imprezę, ale zacytuję, jak mówią: „lepiej spóźnij się niż nigdy”. Więc zacznijmy, każdy ma swoje własne sposoby na wyjaśnienie rzeczy, pozwólcie, że spróbuję to podsumować i wyjaśnić w kilku krokach z przykładem; Załóżmy, że masz prosty formularz, 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" Są to pola / właściwości w StudentClass, gdy formularz jest wywoływany, wywoływane są ich metody pobierające, ale po przesłaniu wywoływane są ich ustawiacze, a ich wartości są ustawiane w komponencie bean wskazanym w modeluAttribute = „student” w znaczniku formularza.

Mamy StudentController, który obejmuje następujące metody;

@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 

teraz w końcu mamy form-details.jsp

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

Wracając do pytania Co to jest @ModelAttribute w Spring MVC? Definicja próbki ze źródła dla Ciebie, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation @ModelAttribute jest adnotacja, że wiąże się to parametr metody lub metoda wartości powrót do określonego atrybutu modelu a następnie udostępnia go do widoku internetowego.

W rzeczywistości dzieje się tak, że pobiera wszystkie wartości formularza, które zostały przez niego przesłane, a następnie przechowuje je, abyś mógł je powiązać lub przypisać do obiektu. Działa tak samo jak @RequestParameter, gdzie otrzymujemy tylko parametr i przypisujemy wartość do jakiegoś pola. Jedyną różnicą jest to, że @ModelAttribute przechowuje wszystkie dane formularza, a nie pojedynczy parametr. Tworzy dla Ciebie fasolę, która przechowuje przesłane dane z formularza do późniejszego wykorzystania przez programistę.

Podsumowując całość. Krok 1: Żądanie jest wysyłane, a nasza metoda showForm działa, a model, ustawiany jest tymczasowy komponent z nazwą studenta przekazywany do formularza. theModel.addAttribute („student”, nowy student ());

Krok 2: modelAttribute = "student" w modelu wysyłania formularza zmienia ucznia i teraz przechowuje wszystkie parametry formularza

Krok 3: @ModelAttribute („student”) Student theStudent Pobieramy wartości przechowywane przez @ModelAttribute i przypisujemy całą fasolę / obiekt Studentowi.

Krok 4: Następnie używamy go podczas licytacji, tak jak pokazujemy go na stronie itp., Tak jak ja

Mam nadzieję, że pomoże ci to zrozumieć tę koncepcję. Dzięki

Majid Ali Khan
źródło
9

Weź dowolną aplikację internetową, bez względu na to, czy jest to Gmail, Facebook, Instagram, czy jakakolwiek inna aplikacja internetowa, chodzi o wymianę danych lub informacji między użytkownikiem końcowym a aplikacją lub interfejsem użytkownika i aplikacją zaplecza. Nawet w świecie Spring MVC istnieją dwa sposoby wymiany danych:

  1. z kontrolera do interfejsu użytkownika oraz
  2. z interfejsu użytkownika do kontrolera.

Interesuje nas tutaj sposób, w jaki dane są przekazywane z interfejsu użytkownika do kontrolera. Można to również zrobić na 2 sposoby:

  1. Korzystanie z formularza HTML
  2. Korzystanie z parametrów zapytania.

Korzystanie z formularza HTML: Rozważ poniższy scenariusz,

Formularz przedłożenia formularza

Kiedy przesyłamy dane formularza z przeglądarki internetowej, możemy uzyskać dostęp do tych danych w naszej klasie Controller jako obiekt. Kiedy przesyłamy formularz HTML, Spring Container robi cztery rzeczy. To będzie,

  1. najpierw przeczytaj wszystkie przesłane dane, które przychodzą do żądania, używając metody request.getParameter .
  2. po ich odczytaniu przekształci je w odpowiedni typ Java za pomocą integer.parseInt , double.parseDouble i wszystkich innych metod analizy dostępnych na podstawie typu danych.
  3. po przeanalizowaniu utworzy obiekt klasy modelu, który stworzyliśmy. Na przykład w tym scenariuszu przesyłane są informacje o użytkowniku, a my tworzymy klasę o nazwie Użytkownik, której Kontener utworzy obiekt i ustawi wszystkie wartości, które zostaną automatycznie wprowadzone do tego obiektu.
  4. przekaże ten obiekt, ustawiając wartości dla kontrolera.

Aby to wszystko zadziałało, będziemy musieli wykonać określone kroki.

Praca wewnętrzna

Najpierw musimy zdefiniować klasę modelu, na przykład Użytkownik, w której liczba pól powinna dokładnie odpowiadać liczbie pól w formularzu HTML. Ponadto nazwy, których używamy w formularzu HTML, powinny pasować do nazw, które mamy w klasie Java. Te dwa są bardzo ważne. Nazwy powinny pasować, liczba pól w formularzu powinna odpowiadać liczbie pól w klasie, którą tworzymy. Gdy to zrobimy, kontener automatycznie odczyta przychodzące dane, utworzy obiekt tego modelu, ustawi wartości i przekaże je kontrolerowi. Aby odczytać te wartości w kontrolerze, używamy @ModelAttributeadnotacja do parametrów metody. Kiedy tworzymy metody w kontrolerze, użyjemy @ModelAttribute i dodamy do niego parametr, który automatycznie otrzyma ten obiekt z kontenera.

Oto przykładowy kod do rejestracji użytkownika:

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

Mam nadzieję, że to schematyczne wyjaśnienie pomogło!

Nithin Prasad
źródło
4

Służy to do celów wiązania danych na wiosnę MVC. Niech masz jsp z elementem formularza np

na JSP

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

(Metoda Spring Form, można również użyć prostego elementu formularza)

Po stronie kontrolera

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

}

Teraz, kiedy prześlesz formularz, wartości pól formularza będą dostępne.

Awais
źródło
4

Adnotacja, która wiąże parametr metody lub wartość zwracaną przez metodę z atrybutem o nazwie modelu, widocznym dla widoku internetowego.

public String add(@ModelAttribute("specified") Model model) {
    ...
}
Byeon0gam
źródło
1

@ModelAttributeutworzy atrybut o nazwie podanej przez Ciebie (@ModelAttribute("Testing") Test test) as Testing w podanym przykładzie, Test będący testem komponentu bean będącym odniesieniem do komponentu bean, a Testowanie będzie dostępne w modelu, abyś mógł dalej używać go na stronach jsp do pobierania przechowywanych wartości w tobie ModelAttribute.

Gagan
źródło
1

@ModelAttribute po prostu wiąże wartość z pól jsp z Pojo calss, aby wykonać naszą logikę w klasie kontrolera. Jeśli znasz rozpórki, jest to jak wypełnianie obiektu formbean po przesłaniu.

Ragu Venkatesan
źródło
0

Adnotacja ModelAttribute jest używana jako część aplikacji internetowej Spring MVC i może być używana w dwóch scenariuszach.

Przede wszystkim można go użyć do wstrzyknięcia danych do modelu ładowania przed JSP. Jest to szczególnie przydatne w celu zapewnienia, że ​​do wyświetlenia wszystkich danych wymagany jest plik JSP. Wstrzyknięcie uzyskuje się przez połączenie jednej metody z modelem.

Po drugie, można go użyć do odczytu danych z istniejącego modelu i przypisania go do parametrów metody trenera.

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

ismael
źródło
0

Na poziomie metody

1. Gdy adnotacja jest używana na poziomie metody, wskazuje, że celem tej metody jest dodanie jednego lub więcej atrybutów modelu

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

W argumencie metody 1. Gdy jest używany jako argument metody, wskazuje, że argument powinien zostać pobrany z modelu. Gdy nie jest obecny i należy go najpierw utworzyć, a następnie dodać do modelu, a po pojawieniu się w modelu, pola argumentów należy wypełnić wszystkimi parametrami żądania, które mają pasujące nazwy. W ten sposób wiąże dane formularza z komponentem bean.

 @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
  public String submit(@ModelAttribute("employee") Employee employee) {
  return "employeeView";
  }
Vivek Srivastava
źródło