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 важными элементами являются:
HandlerMappingHandlerAdapterViewResolverViewHandlerExceptionResolver
Всех их 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 |
|