Разница между @ModelAttribute и org.springframework.ui.ModelMap.get()?

#spring #spring-mvc #annotations

#spring #spring-mvc #примечания

Вопрос:

Я пытаюсь использовать объект в качестве командного объекта <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> элемента.

В методе GET контроллера я добавляю объект следующим образом:

 @RequestMapping(method = RequestMethod.GET)
public String renderForm(ModelMap model, HttpServletRequest request) {
    [...]
    model.addAttribute("voting", voting);
    [...]
}
  

Отображаемая форма правильно отображает объект command, если он определен следующим образом:

 <form:form action="vote" method="PUT" commandName="voting" name="oform">
  

Теперь при попытке получить доступ к командному объекту формы обратно в контроллере с помощью метода POST у меня есть два подхода. Сначала я объявляю атрибут @ModelAttribute в подписи:

 @RequestMapping(method = RequestMethod.PUT)
public String newVoting(@ModelAttribute("voting") Voting voting, HttpServletRequest request) { [...]}
  

Или я получаю доступ к ModelMap и получаю значение из базовой карты:

 @RequestMapping(method = RequestMethod.PUT)
public String newVoting(ModelMap model, HttpServletRequest request) {
    Voting voting = (Voting) model.get("voting");
    [...]
}
  

При выполнении первого я получаю объект в том виде, в каком он был отправлен формой. Выполняя последнее, я получаю объект таким, каким он был ДО обработки формой.

Почему отправка формы не изменяет объект в ModelMap и почему @ModelAttribute отличается от того, что есть в реальной модели? Я чувствую, что имя ‘ModelAttribute’ должно приводить к тому же объекту, что и получение объекта непосредственно из модели.

Может быть, @ModelAttribute вводит в заблуждение?

РЕДАКТИРОВАТЬ Забыл упомянуть, что объект является атрибутом @sessionAttributes

  @SessionAttributes({"voting", "state"})
  

Ответ №1:

Ваш первый подход, использующий аннотацию @ModelAttribute, делает две вещи:

  1. Создание объекта голосования с использованием отправленных данных формы;
  2. Предоставление объекта голосования для просмотра путем добавления его в модель (запрос или, в вашем случае, сеанс из-за атрибутов @sessionAttributes({«голосование»})).

Ваш второй подход использует только ModelMap, поэтому он получает только атрибуты модели (из запроса или, в вашем случае, сеанса, в зависимости от аннотации @sessionAttributes). Этот подход не использует данные из отправленной формы.

Комментарии:

1. Спасибо за ответ. Я знаю, что он не использует данные из формы — но почему? Или почему @ModelAttribute не использует ту же модель, к которой я могу получить доступ через ModelMap?

2. Он не использует данные из формы, потому что вы не «говорите» Spring об этом.