Spring: Web
Делится на 2 больших группы - Spring Web MVC и Spring WebFlow.
Spring Web MVC
Основан на паттерне Model-View-Control. Точкой входа всегда является DispatcherServlet
, который выполняет много работы (определяет карту запросов, локали, временные зоны, добавлеяет возможность загрузки файлов и т.д.). Он преобразует HTTP запрос в команды для контроллеров и помпонентов программы. Так же он возвращает результат действия по запросу.
Dispatcher
плотно работает с ContextLoadListener
, который контролирует работу Spring Context.
Конфигурирование
Компоненты Spring Web можно разделить на 2 группы:
- Компоненты MVC инфраструктуры;
- Handler mappings - определяют куда пойдет запрос (к какому контроллеру), а так же определяет
Listeners
для запроса; - Handler adapters - определяет методы для обработки запросов;
- View resolver - определяют обработчики для ответов;
- Exception resolvers - обработчики ошибок;
- Handler mappings - определяют куда пойдет запрос (к какому контроллеру), а так же определяет
- Компоненты, определенные пользователями;
- Handler interceptor - перехватчик событий, который вносит дополнения в обработку;
- Контроллеры - опрделяют поведение при обработки запроса.
Конфигурационные бины
Помимо DispatcherServlet
важными элементами являются:
HandlerMapping
HandlerAdapter
ViewResolver
View
HandlerExceptionResolver
Всех их DispatcherServlet
пытается найти в качестве реализованных компонентов Spring приложения. По ум. для всех существует реализация в Spring Web MVC, а конфигурация находится в DispatcherServlet
.
Управление компронентами
Используемые аннотации:
@Controller
. Определеяет класс как контроллер;@RequestMapping
. Применим как к классу, так и к методу. Добавляет маппинг на компонент. Может принимать параметрmethod
, который определяет HTTP метод запроса (GET, PUT, POST, DELETE, OPTION и т.д.);@Get/Post/Put/../DeleteMapping
. Быстрая замена для аннотации@RequestMapping
с добавлением параметраmethod
;@PathVariable
. Аннотация параметра метода, который является частью строки URI. Если параметрvalue
не указан, то будет выполнена попытка поиска по схожему имени переменной;@RequestParam
. Параметр, который будет прочитан из строки URI;@RequestHeader
. Параметр, который MVC попытается получить из заголовков запроса;@CookieValue
. Похож на@RequestHeader
, но содержит cookie со стороны клиента;@SessionAttribute
. Содержит именованный атрибуты сессии;@RequestAttribute
. Содержит именованный аттрибут запроса;@ModelAttribute
. Накладывается на метод, который необходимо рассматривать как обработчик каждого метода в контроллере:
1 |
|
@ResponseStatus
. Определяет HTTP код ответа. Рекомендации:- Для POST: если успешно - 200(OK) или 204(No Content). Если
- Для PUT: если успешно - 201(Created), в противном случае - 404(Not found)
Сущности для взаимодействия:
WebRequest
. Объект, который содержит собранную информацию по веб-запросу. Аналоги:NativeWebRequest
,ServletRequest
;ServletResponse
. Объект, который можно использовать для собственной реализации ответа;HttpSession
. Объект с HTTP сессией. Может бытьnull
;PushBuilder
. Позволяет выполнять Push сообщение для клиента. Клиент должен поддерживатьHTTP/2
. Push технология помогает снизить время общего отображения результатов, отправляя Push уведомления на загрузку какого-либо ресурса до(!) получения всего ответа клиентом. Утилита очень удобная и положительно сказывается на времени отображения данных у клиента, но несколько увеличивает нагрузку на сеть;Principal
. Объект содержит инфо об авторизованном пользователе (если используется пакет Spring Security);- HTTP Method. Объект для аудирования и дополнительных проверок;
BindingResult
,Error
,Locale
. Вспомогательные объекты. В современной парадигме сервисной архитектуры, устарели.Reader
,InputStream
. Позволяют читать содержимое тела запроса;Writer
,OutputStream
. Позволяет записывать в содержимое тела ответа;MatrixVariable
. Аналог@RequestParam
, но считывает параметры из URI особым образом. Пример, при URI:some/my/service/path;a=1;b=28;c=7
. Переменные матрицы будут выглядеть так:@MatrixVariable("a") int a
,@MatrixVariable("b") int b
,@MatrixVariable("c") int c
; значениям присвоятся соответствующие параметры. Но в полной мере матрица раскрывается при@MatrixVariable Map<String, Integer> matrix
. По умолчанию, матричные параметры не поддерживаются. Чтобы их включить следует:
1 |
|
RedirectAttributes
. Объект, который управляет перенаправлением клиента с использованиеredirect://...
К нему можно добавить атрибуты любого типа:redirectAttributes.addFlashAttribute("name", "value")
View и View Resolvers
Handler
- полезный и гибки механизм для управления HTTP запросами. В случае с web приложением, возврат имени View
и параметров для его отображения переданные через Model
, применяется повсеместно.
Если Controller
в качестве View
возващает void
, то будет отображаться URL по умолчанию (зависит от конфигурации Spring Web MVC).
В зависимости от провайдера, предоставляющего View
, выполянется соответствующее отображение. В Spring изначально уже есть возможность использования провайдеров JSP, Velocity шаблоны, XSLT представления.
Реализацией ViewResolver
по умолчанию является InternalResourceViewResolver
. В конфигурации или XML это можно изменить.
Конфигурирование ViewResolver
В приложении допустимо использование нескольких ViewResolver
, но в этом случае придется выдать им приоритезацию:
1 |
|
При возврате web методом имени View
, который необходимо использовать, String обходит ViewResolver
согласно указанным приоритетам и вытается получить View
- до тех пор пока не получит его (не null
). Если обошел все View
, но ничего не нашел, будет выкинуто исключение ServerException
.
Клиент так же может выбрать View
, который он хочет получить (введено с Spring 3.0). Существует следующие стратегии выбора View
:
- Посредством URL, к которому выполняется обращение;
- Посредством заголовка
Accept
с указание допускаемого типа клиентом; - Посредством передачи требуемого типа в параметре запроса.
@MVC
Каждый запрос в Spring следует рассматривать так:
- Запрос приходит в
DispatcherServlet
; - Он пытается найти контроллер, который должен обработать соответствующий запрос по требуемому URI;
- Если такого нет - Spring считает что идет обращение к статичному ресурсу (например, jpeg, font, css и т.д.) и передает управление default-servlet-handler (с реализацией по умолчанию
DefaultServletHttpRequestHandler
). По умолчанию в данной реализации поиск осуществляется для всех ресурсов (/*).
Настройка аннотациями
- В каком-либо конфигурационном бине (
@Configuration
) добавить аннотацию@EnableWebMvc
; - и/или добавить реализацию этим бином интерфейса
WebMvcConfigurerAdapter
(или наследоваться от стандартной реализацииWebMvcConfigurer
).
Упрощенная настройка
Начиная с Spring 3.0 инициализация упрощается с введением WebApplicationInitializer
.
1 | public class MyWebINit implements WebApplicationInitializer { |
Но если использовать аннотацию @EnableWebMvc
, то инициализация может немного измениться:
1 | registration.setInitialParameter("contextConfigurationLocation", "my.conf.mvc.WebConfig"); |
Перехват ошибок
В Spring осуществляется реализацией HandlerExceptionResolver
. Handler
может быть несколько и всех их можно упорядочить в определенном порядке для обработки специфическим способом особые исключения.
Эту задачу выполяняет ExceptionHandlerExceptionResolver
- вызывает методы с аннотацией @ExceptionHandler
у класса с аннотацией @ControllerAdvice
.
Так же следует обратить внимание на ResponseStatusExceptionResolver
- он выполняет методы с аннотацией @ResponseStatus
для возврата соответствующего статуса HTTP.
И, наконец, DefaultHandlerExceptionResolver
- обрабатывает ошибки Spring MVC и отдает соответствующий статус.
HandlerExceptionResolver
Реализация данного интерфейса важна для перехвата исключений в Spring MVC:
1 | public class MyExceptionHandler extends SimpleMappingExceptionResolver { |
Существует сделаюущие особенности с HandlerExceptionResolver
:
- Возвращает
ModelAndView
, который определяет тип исключения и выдает соответствующую ошибку; - Может вернуть
null
, если не удалось установить обработку исключения - в таком случае исключение передается другимHandler
. Если ни одинHandler
не смог установить отбработчика исключения, оно передается на обработку в Server Container (т.е. серверу приложений); - Можно создать бин этого типа и определить ему максимальный приоритет -
HIGHEST_PRECEDENCE
. Тогда бин будет обрабатывать исключения первый и всегда.
Обработка через @ExceptionHandler
Можно обязать компонент (в т.ч. Controller
) обрабатывать исключения определенного типа:
1 |
|
При этом, почти все параметры (точнее, типы), которые получает web-метод перехватчика (Controller
) может получать и @ExceptionHandler
. Причем, тип ошибки можно передать в аннотации, а из параметров убрать:
1 |
|
@ControllerAdvice
Является негласным стандартным бином для отлова всех исключений. Аннотация наследуется от @Controller
, так что уже является Spring компонентом:
1 |
|
Тестирование MVC
1 |
|