Часть 3. Java. Spring MVC: Контроллер

Написано 17 Ноябрь, 2014 в категории Java,Разработка ПО


Контроллер является связующим звеном между представлением и моделью данных. Фактически доступ к данным происходит через контроллеры. Схема проста, пользователь вводит в барузер ссылку на сайт. Эту ссылку обрабатывает контроллер, т.е. он определяет какой вид необходимо вернуть для отображения пользователю и какие данные для этого необходимо запросить у модели.

В Spring MVC существует 2 способа пометить класс как контроллер:
1. Добавить к классу аннотацию @Controller (org.springframework.stereotype.Controller)
2. Класс должен реализовывать интерфейс Controller (org.springframework.web.servlet.mvc.Controller)

Несмотря на то, что оба способа позволяют определить контроллер, ни не являются одинаково удобными в работе. Использование аннотаций позволяет более гибко работать с маппингом URL. Суть отличия состоит в том что в случае использования интерфейса маппинг URL всех контроллеров будет определен в одном месте, но отдельно от контроллеров, а в случае аннотаций маппинг будет "размазан" по контроллерам. Далее мы рассмотрим метод конфигурации контроллера с помощью аннотаций.

Пример 1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package ru.stasyak.spring.example.web;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
@Controller
public class IndexController {
 
    @RequestMapping(value = "/index.htm")
    public ModelAndView indexPage() {
        return new ModelAndView(“index");
    }
 
}

Добавили к классу аннотацию @Controller, теперь Spring при сканировании исходного кода будет определять этот класс как контроллер. Далее мы добавили метод indexPage и с помощью аннотации @RequestMapping указали фреймворку, что все запросы вида http(s)://domain_name/index.html будут обработаны этим методом.

Рассмотрим подробнее как работает @RequestMapping. Эта аннотация позволяет сопоставить запрос, который должно обработать web-приложение и метод контроллера, который должен этот запрос обработать. @RequestMapping умеет различать запросы по url, методу отправки запроса, набору параметров в заголовке или даже по типу контента в запросе. Мы может указать данную аннотацию одновременно как для всего контроллера, так и для отдельных методов при этом url указанный для всего контроллера (параметр аннотации value) будет общим для методов.

Параметры аннотации @RequestMapping

valueОписывает URL, который будет обработан в данном контроллере или методе контроллера.
methodСвязывает метод контроллера с обработкой запросов отправленных определенным HTTP методом или методами (GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE). Набор констант для http-методов находится в классе RequestMethod (org.springframework.web.bind.annotation.RequestMethod). По умолчанию, запросы отправленные методом OPTIONS и TRACE обрабатываются в DispatcherServlet ( org.springframework.web.servlet.DispatcherServlet). Если метод контроллера должен обрабатывать запросы отправленные одним из нескольких http-методов, то записываем это таким образом, например,
method={RequestMethod.PUT, RequestMethod.POST}.
paramsзапрос фильтруется по наличию или отсутствию параметров в запросе.

param-name=param-valueв запросе должен быть параметр param-name со значением param-value
param-name!=param-valueв запросе параметр param-name не должен содержать значение param-value
!param-nameзапрос не должен содержать параметра с названием param-name
headers запрос фильтруется по наличию или отсутствию параметров в заголовке.

param-name=param-valueв заголовке запроса должен быть параметр param-name со значением param-value
param-name!=param-valueв заголовке запроса параметр param-name не должен содержать значение param-value
!param-nameв заголовке запроса не должено быть параметра с названием param-name

В значениях параметров можно указывать символ * для описания подмножества, например, для параметра Content-Type можно задать content-type="text/*" ???

consumesпозволяет фильтровать запросы по типу содержимого. Сравнивается с параметром заголовка Content-Type. Если данный параметр отсутствует, то Spring попытается определить тип самостоятельно. Также можно использовать символ * для указания подмножества типов, например "application/*".
producesпозволяет фильтровать запросы по ожидаемому типу содержимого ответа. Сравнивается со значением параметра Accept. Если данный параметр отсутствует, то Spring попытается определить тип самостоятельно. Также можно использовать символ * для указания подмножества типов, например "application/*".