2016-06-23 5 views
2

Я новичок в Spring MVC. Удалось запустить некоторые приложения, но у меня есть некоторые сомнения в том, как все работает в определенном направлении, и я не могу найти объяснение, которое я ищу. В частности, в этом методе:Понимание того, как работает разрешение модели

@Controller 
@RequestMapping("/hello") 
public class HelloController{ 

    @RequestMapping(method = RequestMethod.GET) 
    public String printHello(ModelMap model) { 
     model.addAttribute("message", "Hello Spring MVC Framework!"); 
     return "hello"; 
    } 

} 

Я знаю "Hello Spring MVC Framework!" (под названием message) в настоящее время передается в представлении. Но есть две вещи, которые волнуют меня, и найти немного необычное:

  1. Почему model объявлен как входного параметра метода printHello? а не как локальная переменная?
  2. model нигде не передается на вид явно, так ли это происходит за кулисами?
+0

Я так думаю, когда DispatcherServlet обращается к HandlerMapping для вызова соответствующего контроллера, возможно, он создает собственный объект ModelMap, чтобы передать объект объекту аргументу метода. И если вы объясните, как построить его через локальную инстанцию, то объект не управляется обработчиком, следовательно, привязка не происходит. Поэтому можно просто рассматривать это как соглашение/соглашение, что-то в этом роде. –

ответ

2

Почему 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)

Front Controller просто знаю, что возвращается ваш метод контроллера и может понять, если это новая модель или ваш метод не вернулся какой-либо модели, а затем Front Controller использует модель, которую она передается в ваш метод управления в качестве аргумента.

1

@RequestMapping аннотаций вы предоставили это делает волшебным. Я говорю это как в буквальном, так и в метафорическом смысле. Это в основном устраняет беспорядок ручной проводки, который обычно будет включать в себя.

  1. модель является одним из многих дополнительных входных параметров. Вы могли бы, если бы захотели, предоставить больше или меньше, или нет. В этом случае вы хотите использовать ModalMap, поэтому вы говорите: «Я хочу использовать ModalMap», включив аргумент. Если у вас есть аргументы, исходящие из запроса, например, в заголовке, вы можете добавить их и приложить к ним.

  2. Это похоже на @Autowire весной. Когда вы выполняете аудит службы, вы никогда явно не говорите new FooService() в любом месте, но она автоматически создается и управляется для вас весной. Вы в основном выгружаете большую часть проводки на Spring, и она обрабатывает весь шаблон, когда вы обрабатываете именно то, что вам нужно для его обработки.

В этом случае, вы передаете ModalMap со значением для клиента из запроса GET, а затем значение загружается на этой странице.

Дополнительная литература + Источник: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html

+0

моя точка была: (1) мне было странно видеть модель в качестве входного параметра, и (2) я не вижу, явно передается в представление. PS. Также в этом случае единственный текст, отображаемый в представлении, является тем, который я представил в коде, поэтому я полагаю, что другие данные не получены, например. с GET. –

+1

Что касается № 2, это сродни этому. 'Foo foo = new Foo(); String s = doSomething (foo); 'Spring все еще имеет ссылку на' foo' в этом случае. Не нужно также возвращать «foo» и туда, где он помогает загрузке страницы. Так как это единственный метод GET, и он не имеет аргументов, вы могли бы вызвать метод, какой бы вы ни хотели, и он все равно будет целевым методом для ответа. – Compass

0

новыйmodel объект, созданный рамках Spring MVC-для каждого request.That почему это не локальная переменная. Так как сам объект, созданный каркасом, уже имеет ссылку, он так заставляет его передавать его в представление.

1

Подумайте об model объект передан как аргумент, аналогичный объекту HttpServletRequest, который я добавил ниже в вашем коде. Spring генерирует неявный модельный объект, который доступен на протяжении всего жизненного цикла запроса, подобно неявному объекту request, доступному для JSP. Таким образом, для каждого жизненного цикла запроса этот неявный объект модели будет совместно использоваться контроллером и представлением.

@Controller 
@RequestMapping("/hello") 
public class HelloController{ 

    @RequestMapping(method = RequestMethod.GET) 
    public String printHello(ModelMap model, HttpServletRequest req) { 
     model.addAttribute("message", "Hello Spring MVC Framework!"); 
     return "hello"; 
    } 

} 

Ниже приведено описание от spring docs.где упоминаются, что значение входного Params, которые передаются методы снабженного @RequestMapping

Карта/модели/ModelMap для обогащения неявной модели, которая будет воздействию веба-просмотр.

 Смежные вопросы

  • Нет связанных вопросов^_^