Spring MVC - IrinaSerebryakova/ITQuestions GitHub Wiki

1. Для чего предназначен модуль Spring MVC.

Spring MVC – Это модуль spring, который позволяет писать веб приложения с использованием паттерна MVC. Главной целью Spring MVC является разделение объектов, бизнес-логики и внешнего вида приложения. Все эти компоненты слабо связаны между собой и при желании мы можем изменить, например, внешний вид приложения, не внося существенные изменения в остальные два компонента.

  • Модель (Model) предоставляет данные и реагирует на команды контроллера, изменяя своё состояние.
  • Представление (View) отвечает за отображение данных модели пользователю, реагируя на изменения модели.
  • Контроллер (Controller) интерпретирует действия пользователя, оповещая модель о необходимости изменений.

В Spring MVC Model работает, как контейнер для объектов, которые используются при рендеринге view. Т.е. мы кладем в модель какие-то данные и они будут доступны во view. Модель является бином с request scope. Концептуально модели можно рассматривать, как мапы. Есть 3 основные, независимые иерархии моделей:

  • interface Model
  • class ModelMap
  • class ModelAndView

Представление (View) - Модуль представления отвечает за вывод данных пользователю. Обычно это JSP файл, который может быть опознан и интерпретирован браузером на пользовательской машине. View это по сути бины, которые на вход принимают модель с атрибутами, на выходе отдает html. ViewResolver позволяет зарезолвить (определить) конкретную вью по имени и локали. В этом интерфейсе определен единственный метод

Контроллер (Controller) - отвечает за обработку запросов пользователей и передачу данных модулю View для обработки.

2. Для чего нужен Dispatcher Servlet.

Spring MVC построен вокруг центрального сервлета, который распределяет запросы по контроллерам, а также предоставляет другие широкие возможности при разработке веб приложений. На самом деле DispatcherServlet — полностью интегрированный сервлет в Spring IoC контейнер и таким образом получает доступ ко всем возможностям Spring.

Вся логика работы Spring MVC построена вокруг DispatcherServlet, который принимает и обрабатывает все HTTP-запросы (из UI) и ответы на них.

image

Ниже приведена последовательность событий, соответствующая входящему HTTP-запросу:

DispatcherServlet является реализацией паттерна front controller. Суть которого заключается в том, чтобы принимать все запросы, делегировать их выполнение другим модулям и отдавать ответ потребителям.

  • После получения HTTP-запроса DispatcherServlet обращается к интерфейсу HandlerMapping, который определяет, какой Контроллер должен быть вызван, после чего, отправляет запрос в нужный Контроллер.

  • Контроллер принимает запрос и вызывает соответствующий служебный метод, основанный на GET или POST. Вызванный метод определяет данные Модели, основанные на определённой бизнес-логике и возвращает в DispatcherServlet имя Вида (View).

  • При помощи интерфейса ViewResolver DispatcherServlet определяет, какой Вид нужно использовать на основании полученного имени.

  • После того, как Вид (View) создан, DispatcherServlet отправляет данные Модели в виде атрибутов в Вид, который в конечном итоге отображается в браузере.

Все вышеупомянутые компоненты, а именно, HandlerMapping, Controller и ViewResolver, являются частями интерфейса WebApplicationContext extends ApplicationContext, с некоторыми дополнительными особенностями, необходимыми для создания web-приложений.

image

3. Какую функцию выполняют HandlerInterceptors?

HandlerInterceptor являются частью среды Spring MVC и находятся между DispatcherServlet и нашим Controller. Мы можем перехватывать запросы до того, как они достигнут наших контроллеров, а также до и после рендеринга представления. Чтобы создать HandlerInterceptor, мы создаем класс, реализующий интерфейс org.springframework.web.servlet.HandlerInterceptor.

Это дает нам возможность переопределить три метода:

  • preHandle() – выполняется до вызова целевого обработчика
  • postHandle() — выполняется после целевого обработчика, но до того, как DispatcherServlet отобразит представление.
  • afterCompletion() – Обратный вызов после завершения обработки запроса и рендеринга представления.

Фильтры перехватывают запросы до того, как они достигнут DispatcherServlet , что делает их идеальными для крупномасштабных задач, таких как:

  • Аутентификация
  • Ведение журнала и аудит
  • Сжатие изображений и данных
  • Любая функциональность, которую мы хотим отделить от Spring MVC. HandlerIntercepors перехватывает запросы между DispatcherServlet и нашим Controller. Это делается в рамках Spring MVC, обеспечивая доступ к объектам Handler и ModelAndView . Это обеспечивает более детальную функциональность, например:
  • Решение сквозных проблем, таких как ведение журнала приложений.
  • Подробные проверки авторизации
  • Манипулирование контекстом или моделью Spring

image

4. Какие существуют обработчики исключений в модуле Spring MVC

HandlerExceptionResolver является общим интерфейсом для обработчиков исключений в Spring. Все исключения, выброшенные в приложении, будут обработаны одним из подклассов HandlerExceptionResolver. Можно сделать как свою собственную реализацию данного интерфейса, так и использовать существующие реализации, которые предоставляет нам Spring из коробки:

ExceptionHandlerExceptionResolver — этот резолвер является частью механизма обработки исключений с помощью аннотации @ExceptionHandler.

DefaultHandlerExceptionResolver — используется для обработки стандартных исключений Spring и устанавливает соответствующий код ответа, в зависимости от типа исключения. Основной недостаток заключается в том что возвращается только код статуса, а на практике для REST API одного кода часто не достаточно. Желательно вернуть клиенту еще и тело ответа с описанием того что произошло.

ResponseStatusExceptionResolver — позволяет настроить код ответа для любого исключения с помощью аннотации @ResponseStatus. Из недостатков такого подхода — как и в предыдущем случае отсутствует тело ответа. Но если нужно вернуть только код статуса, то @ResponseStatus довольно удобна.

Начиная со Spring 3.2 можно глобально и централизованно обрабатывать исключения с помощью классов с аннотацией @ControllerAdvice.

Можно одним методом обрабатывать и несколько исключений сразу с помощью аннотации @ExceptionHandler.

5. Какие контексты существуют в Spring MVC.

Прежде чем переходить к контекстам, необходимо знать, что Spring может иметь несколько контекстов, один из них будет родительским контекстом (root context), другой дочерним (child context). Все дочерние контексты имеют доступ к бинам, расположенным в родительском контексте, но не наоборот.

Когда мы пишем Spring MVC приложения, у нас появляется множество бинов из коробки (HandlerMapping, ViewResolver и тд), все они находятся в дочернем контексте. Каждый DispatcherServlet прогружает свой контекст (Обычным приложениям хватает одного DispatcherServlet’a).

Вы можете иметь один root контекст, в случае если у вас простое веб приложение с одним DispatcherServlet.