Почему model
объявлен в качестве входного параметра в метод printHello
? а не как локальная переменная?
Вы можете объявить его как локальную переменную и вернуть его, если вы хотите:
@RequestMapping("/hello")
public ModelMap printHello() {
return new ModelMap("message", "Hello Spring MVC Framework!");
}
Но этот путь вы не воспользоваться данными Спринга связывания (связывание запроса атрибутов (параметров запроса для запроса GET) моделировать).
Кроме того, этот способ не предоставляя никакого имени вида (как в исходном примере return "hello"
), поэтому Spring MVC будет выводить его с помощью по умолчанию DefaultRequestToViewNameTranslator
, который использует имя контроллера без Controller
суффикса как логическое имя вида (в вашем примере это будет hello
потому что ваш контроллер HelloController
). См. documentation для получения дополнительной информации.
Также вы можете вернуть новый экземпляр ModelAndView
вместо Model
или ModelMap
. В этом случае вы можете явно указать атрибуты имени представления и модели.
Но главным преимуществом использования аргумента метода Model как обработчика является привязка данных.
Когда вы предоставляете модели и некоторого атрибут модели (привязать запрос) в качестве аргументов методы, то вы получите экземпляр модели с уже добавлена (и заполненными с помощью запроса Params) атрибута модели к модели, а затем вы можете добавить другой атрибут к нему, если вам это нужно.
@RequestMapping(path = "/hello", method = RequestMethod.GET)
public String printHello(Model model, @ModelAttribute("form") SearchForm form, BindingResult result) {
model.addAttribute("anotherUsefulValue", myService.getSomeValue());
// 'hello' view will get the model with both 'form' and 'anotherUsefulValue' attributes
// and 'form' attribute will have 'text' field filled from request's
// query parameter 'text'.
return "hello";
}
class SearchForm {
private String text;
// ... getter and setter
}
Используя этот метод, вы можете сделать GET запрос от некоторых HTML form
с текстовым полем с именем text
и когда вы отправляете эту форму, ваша модель будет содержать атрибут form
с реализованным SearchForm
объекта в качестве значения. И поле text
этого объекта будет иметь параметр запроса text
как значение.
Пример использования spring-form JSP Tag Library:
<form:form method="GET" action="/hello" modelAttribute="form">
<form:input path="text" />
<input type="submit">
</form>
Или просто введите URL /hello?text=12345
. И вы увидите, что model
будет иметь атрибут form
с полем text
, равным 12345
и он также имеет свой атрибут anotherUsefulValue
. Вы просто привязали данные Spring к своим пользовательским атрибутам модели.
Конечно, вы можете создать новую модель вручную и установить anotherUsefulValue
вместе с атрибутом form
из аргумента метода form
. Но это просто более шаблонный.
model
нигде не передается в представление явно, так это происходит за кулисами как-то?
Конечно. Весна DispatcherServlet
сделайте это для вас как можно больше. Все это описано в documentation.
![The request processing workflow in Spring Web MVC (high level)](https://i.stack.imgur.com/ZHkb2.png)
Front Controller
просто знаю, что возвращается ваш метод контроллера и может понять, если это новая модель или ваш метод не вернулся какой-либо модели, а затем Front Controller
использует модель, которую она передается в ваш метод управления в качестве аргумента.
Я так думаю, когда DispatcherServlet обращается к HandlerMapping для вызова соответствующего контроллера, возможно, он создает собственный объект ModelMap, чтобы передать объект объекту аргументу метода. И если вы объясните, как построить его через локальную инстанцию, то объект не управляется обработчиком, следовательно, привязка не происходит. Поэтому можно просто рассматривать это как соглашение/соглашение, что-то в этом роде. –