Что такое @ModelAttribute в Spring MVC?

372

Какова цель и использование @ModelAttributeв Spring MVC?

Мохаммад Аднан
источник
40
Я думаю, что это полезный вопрос, потому что он позволяет читателям получать больше информации (включая примеры), чем предоставляет официальная документация Spring.
anton1980
3
Проверьте это рецензию здесь. thespringthing.blogspot.com/2010/11/…
praveenj

Ответы:

399

@ModelAttributeссылается на свойство объекта Model (M в MVC;), так что, скажем, у нас есть форма с объектом поддержки формы, который называется «Person». Затем вы можете заставить Spring MVC передать этот объект в метод Controller с помощью @ModelAttributeаннотации. :

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

С другой стороны, аннотация используется для определения объектов, которые должны быть частью модели. Поэтому, если вы хотите, чтобы объект Person упоминался в модели, вы можете использовать следующий метод:

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

Этот аннотированный метод позволит получить доступ к объекту Person в вашем представлении, поскольку он автоматически добавляется в модели Spring.

Смотрите раздел «Использование @ModelAttribute» .

fasseg
источник
8
@fasseg Тебе не нужно @ModelAttributeв первом случае.
Нил Макгиган
@Neil Когда вам нужно использовать @ModelAttributeв атрибутах метода?
Райан
4
@Ryan см stackoverflow.com/questions/8688135/...
Neil МакГигана
1
Вы должны указать, как заполнен объект Person и как вызывается этот метод.
Филипп Рего
134

Я знаю, что это старая нить, но я подумал, что я брошу свою шляпу в кольцо и посмотрю, смогу ли я немного запачкать воду :)

Я обнаружил, что моя первая попытка понять @ModelAttribute- это результат решения Spring объединить несколько аннотаций в одну. Это стало яснее, когда я разделил его на несколько небольших аннотаций:

Что касается аннотаций параметров, то их можно считать @ModelAttributeэквивалентом, @Autowired + @Qualifierт. Е. Он пытается извлечь компонент с заданным именем из управляемой модели Spring. Если именованный компонент не найден, вместо выдачи ошибки или возврата nullон неявно принимает на себя роль@Bean т. Е. Создает новый экземпляр, используя конструктор по умолчанию, и добавляет компонент в модель.

Что касается аннотаций методов, то их можно рассматривать @ModelAttributeкак эквивалент @Bean + @Before, т. Е. Он помещает в модель компонент, созданный кодом пользователя, и всегда вызывается перед методом обработки запроса.

Образно говоря, я вижу @ModelAttributeследующее (пожалуйста, не воспринимайте это буквально !!):

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

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

Как видите, Spring принял правильное решение сделать @ModelAttributeвсеобъемлющую аннотацию; никто не хочет видеть аннотацию шведского стола.

Кристофер Ян
источник
2
Хм, @Bean по умолчанию одноэлементный. Я не уверен, что здесь применимы те же понятия.
Зомби
10
Точно нет. Я просто использую более простые аннотации, чтобы объяснить эту сложную аннотацию. Пожалуйста, примите мое объяснение концептуально, а не буквально.
Кристофер Ян
4
@ Зомби добавить @Scope("request")потом :)
OrangeDog
28

Для моего стиля я всегда использую @ModelAttribute, чтобы поймать объект из пружинной формы jsp. например, я проектирую форму на странице jsp, эта форма существует с commandName

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

и я ловлю объект на контроллере с последующим кодом

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

и каждое имя поля книги должно совпадать с путем в подэлементе формы

Leang Socheat
источник
4
catchГлагол точно описывает работу, @ModelAttributeпроделанную. Ницца.
Эдди
3
Лучший ответ года.
Юпитер Cls
4
Но нужно ли это? Это все еще работает без использования аннотации @ModelAttribute.
23

Поэтому я попытаюсь объяснить это более простым способом. Давайте:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

Как описано в документации Spring MVC, аннотация @ModelAttribute может использоваться для методов или аргументов метода . И, конечно, мы можем одновременно использовать их в одном контроллере.

1. Метод аннотации

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

Цель такого метода - добавить атрибут в модель. Таким образом, в нашем случае ключ городов будет иметь список в new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})качестве значения в модели (вы можете думать о модели как о карте (ключ: значение)). Методы @ModelAttribute в контроллере вызываются до методов @RequestMapping внутри того же контроллера.

Здесь мы хотим добавить к Модели общую информацию, которая будет использоваться в форме для отображения пользователю. Например, его можно использовать для заполнения HTML-выбора:

введите описание изображения здесь

2. Метод аргументации

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

@ModelAttribute в аргументе метода указывает, что аргумент должен быть получен из модели. Так что в данном случае мы ожидаем , что мы имеем в модели человека объект как ключ , и мы хотим , чтобы получить его значение и поместить его в метод аргумента Person человека . Если такого не существует или (иногда вы неправильно пишете (value = "persson")), то Spring не найдет его в модели и создаст пустой объект Person с использованием значений по умолчанию. Затем возьмем параметры запроса и попытаемся связать их данные в объекте Person, используя их имена.

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

Итак, у нас есть имя, и оно будет привязано к Person.name с помощью setName (String name). Так в

//..Some logic with person

у нас есть доступ к этому заполненному имени со значением «Димитрий».

Конечно, Spring может связывать более сложные объекты, такие как списки, карты, списки наборов карт и так далее, но за сценой это делает магию привязки данных.

  1. Мы можем одновременно иметь аннотированный метод и обработчик метода запроса с @ModelAttribute в аргументах. Тогда мы должны объединить правила.

  2. Конечно, у нас есть множество различных ситуаций - методы @ModelAttribute также могут быть определены в @ControllerAdvice и так далее ...

Xelian
источник
13

Я знаю, что опаздываю на вечеринку, но я процитирую, как говорят, «лучше опаздывать, чем никогда». Итак, давайте начнем. У каждого есть свои способы объяснить вещи, позвольте мне подвести итог и упростить для вас несколько шагов с примером; Предположим, у вас есть простая форма, 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" Это поля / свойства в StudentClass, когда форма вызывается, их вызывающие методы вызываются, но после отправки их вызывающие методы устанавливаются, и их значения устанавливаются в bean-компоненте, указанном в modelAttribute = «студент» в форме тега.

У нас есть StudentController, который включает следующие методы;

@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 

теперь, наконец, у нас есть form-details.jsp

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

Итак, вернемся к вопросу Что такое @ModelAttribute в Spring MVC? Определение выборки из источника для вас, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation @ModelAttribute является аннотацией , которая связывает параметр метода или метод возвращает значение к имени атрибута модели а затем выставляет его на веб-просмотр.

Что на самом деле происходит, так это то, что он получает все значения вашей формы, которые были переданы им, а затем хранит их, чтобы вы могли связать или присвоить их объекту. Он работает так же, как @RequestParameter, где мы получаем только параметр и присваиваем значение некоторому полю. Разница лишь в том, что @ModelAttribute содержит все данные формы, а не один параметр. Он создает для вас bean-компонент, который содержит отправленные данные формы для последующего использования разработчиком.

Подведем итоги. Шаг 1: Запрос отправлен, и наш метод showForm запускается, и модель, в которой установлен временный бин с именем ученика, перенаправляется в форму. theModel.addAttribute («студент», новый студент ());

Шаг 2: modelAttribute = "student" при отправке формы модель меняет студента, и теперь она содержит все параметры формы

Шаг 3: @ModelAttribute ("student") Student theStudent Мы извлекаем значения, удерживаемые @ModelAttribute, и назначаем весь объект EJB-объект Student.

Шаг 4: И затем мы используем его в качестве ставки, так же, как показывать его на странице и т. Д., Как я сделал

Я надеюсь, что это поможет вам понять концепцию. Спасибо

Маджид Али Хан
источник
9

Возьмите любое веб-приложение, будь то Gmail, Facebook, Instagram или любое другое веб-приложение, это все об обмене данными или информацией между конечным пользователем и приложением или пользовательским интерфейсом и внутренним приложением. Даже в мире Spring MVC есть два способа обмена данными:

  1. от контроллера к пользовательскому интерфейсу, и
  2. от пользовательского интерфейса до контроллера.

Здесь нас интересует, как данные передаются из интерфейса в контроллер. Это также можно сделать двумя способами:

  1. Использование формы HTML
  2. Использование параметров запроса.

Использование формы HTML: рассмотрим следующий сценарий:

Представление формы представления

Когда мы отправляем данные формы из веб-браузера, мы можем получить доступ к этим данным в нашем классе Controller как объект. Когда мы отправляем HTML-форму, Spring Container выполняет четыре вещи. Это будет,

  1. сначала прочитайте все данные, представленные в запросе, используя метод request.getParameter .
  2. как только он их прочитает, он преобразует их в соответствующий тип Java, используя integer.parseInt , double.parseDouble и все другие методы синтаксического анализа, доступные в зависимости от типа данных данных.
  3. после анализа он создаст объект класса модели, который мы создали. Например, в этом сценарии отправляется информация о пользователе, и мы создаем класс с именем User, для которого контейнер будет создавать объект, и он будет устанавливать все значения, которые автоматически входят в этот объект.
  4. Затем он передаст этот объект, установив значения для контроллера.

Чтобы заставить все это работать, мы должны следовать определенным шагам.

Внутренняя работа

Сначала нам нужно определить класс модели, такой как User, в котором количество полей должно точно соответствовать количеству полей в HTML-форме. Кроме того, имена, которые мы используем в форме HTML, должны соответствовать именам, которые есть в классе Java. Эти два очень важны. Имена должны совпадать, количество полей в форме должно совпадать с количеством полей в классе, который мы создаем. Как только мы это сделаем, Контейнер автоматически прочитает поступающие данные, создаст объект этой модели, установит значения и передаст его Контроллеру. Чтобы прочитать эти значения внутри контроллера, мы используем @ModelAttributeаннотация по параметрам метода. Когда мы создаем методы в Контроллере, мы собираемся использовать @ModelAttribute и добавить к нему параметр, который автоматически получит этот объект от Контейнера.

Вот пример кода для регистрации пользователя:

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

Надеюсь, что это схематическое объяснение помогло!

Нитин Прасад
источник
4

Это используется для привязки данных в Spring MVC . Пусть у вас есть jsp с элементом формы, например

на JSP

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

(Метод Spring Form, простой элемент формы также может быть использован)

На стороне контроллера

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

}

Теперь при отправке формы вам будут доступны значения полей формы.

Awais
источник
4

Аннотация, которая связывает параметр метода или возвращаемое значение метода с именованным атрибутом модели, доступным для веб-представления.

public String add(@ModelAttribute("specified") Model model) {
    ...
}
Byeon0gam
источник
3

@ModelAttribute может использоваться как аргументы / параметр метода или перед объявлением метода. Основная цель этой аннотации - привязать параметры запроса или поля формы к объекту модели

Ссылка http://www.javabeat.net/modelattribute-spring-mvc/

Четан Д
источник
1

@ModelAttributeсоздаст атрибут с именем, указанным вами (@ModelAttribute("Testing") Test test) as Testing в данном примере, Test - это bean-тест, являющийся ссылкой на bean-компонент, и Testing будет доступен в модели, чтобы вы могли в дальнейшем использовать его на страницах jsp для получения значений, которые вы сохранили в тебе ModelAttribute.

Gagan
источник
1

@ModelAttribute просто связывает значение из полей jsp с календарем Pojo для выполнения нашей логики в классе контроллера. Если вы знакомы с распорками, то это похоже на заполнение формбэя при отправке.

Рагу Венкатесан
источник
0

Аннотация ModelAttribute используется как часть веб-приложения Spring MVC и может использоваться в двух сценариях.

Прежде всего, его можно использовать для ввода данных в модель нагрузки до JSP. Это особенно полезно для обеспечения того, что JSP требуется для отображения всех данных. Инъекция получается путем подключения одного метода к модели.

Во-вторых, его можно использовать для считывания данных из существующей модели и назначения их параметрам метода тренера.

ссылка https://dzone.com/articles/using-spring-mvc%E2%80%99s

Исмаэль
источник
0

На уровне метода

1. Когда аннотация используется на уровне метода, она указывает, что целью этого метода является добавление одного или нескольких атрибутов модели.

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

Аргумент метода 1. При использовании в качестве аргумента метода он указывает, что аргумент должен быть получен из модели. Если он отсутствует и должен быть сначала создан, а затем добавлен в модель и представлен в модели, поля аргументов должны быть заполнены всеми параметрами запроса, имеющими совпадающие имена. Таким образом, он связывает данные формы с бином.

 @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
  public String submit(@ModelAttribute("employee") Employee employee) {
  return "employeeView";
  }
Вивек Шривастава
источник