Одна из неприятных особенностей любого фреймворка — необходимость выполнения целого ряда типовых действий для того чтобы получить минимально работоспособный проект. К сожалению, Spring MVC не исключение.
В случае Spring MVC можно выделить две категории проектов, в зависимости от архитектуры.
- Проекты на основе XML конфигурации;
- Проекты с использованием аннотаций.
Первые используют для определения контроллеров и маршрутизации XML файл DispatcherServlet. Вторые используют для этого аннотации.
В этой статье мы рассмотрим первый тип проектов.
Однако, хотелось бы ещё раз подчеркнуть, что материал данной статьи применим только для Spring 4 или некоторых более ранних версий.
Архитектуру Spring MVC рассматривать мы не будем, так как она достаточно подробно описана в документации (в крайнем случае, ей будет посвящена отдельная статья), а сразу перейдём к практике. То есть, данная статься представляет собой своего рода «быстрый старт» для создания нового проекта или понимания работы существующего.
Контроллеры
Функционал контроллеров реализуется специальными классами из пакета org.springframework.web.servlet.mvc. В основном это:
- ParameterizableViewController.
Просто выдаёт заданное в XML файле конфигурации JSP представление; - AbstractController.
Абстрактный класс, который служит основой для создания контроллеров-действий (поддерживают только одно действие); -
MultiActionController (находится в пакете org.springframework.web.servlet.mvc.multiaction).
Абстрактный класс, предоставляющий основу для обычных контроллеров, которые поддерживают несколько действий.
С ParameterizableViewController всё предельно просто. Это уже полностью готовый контроллер и весь необходимый функционал в нём уже реализован. Нужно лишь объявить его как обычный компонент Spring с указанием нужного представления.
AbstractController содержит лишь один метод, который требуется переопределить в классе наследнике — handleRequestInternal. Собственно он и отвечает за реализацию единственного действия контроллера.
Однако для работы контроллера этого недостаточно. Нужно добавить ещё два обязательных метода для установки и чтения имени JSP представления, а также поле для его хранения.
Ниже приведён пример подобного контроллера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class HomeController extends org.springframework.web.servlet.mvc.AbstractController { private String viewName; public String getViewName() { return viewName; } public void setViewName(String viewName) { this.viewName = viewName; } public HomeController() { } @Override protected ModelAndView handleRequestInternal(HttpServletRequest hsr, HttpServletResponse hsr1) throws Exception { return new ModelAndView(); } } |
Контроллеры на основе класса MultiActionController лишены подобных недостатков, и как уже говорилось ранее, поддерживают выполнение нескольких действий. Также для подобных контроллеров не обязательно задавать JSP представления в файле конфигурации. Это можно сделать непосредственно в самом классе.
Ниже представлен пример контроллера на основе MultiActionController.
1 2 3 4 5 6 7 8 |
public class MultiController extends MultiActionController { public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("multi/index"); } public ModelAndView test(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("multi/test"); } } |
Обратите внимание на формат имени представления. Оно начинается с папки в которой расположены файлы представлений относящихся к данному контроллеру. После идёт символ «/» и только после него само имя представления.
Размещать представления для таких контроллеров в отдельных папках не обязательно (тогда можно ограничиться просто именем представления), но крайне желательно во избежание путаницы.
Что касается старых проектов, то при миграции на Spring 5 соответствующие фрагменты придётся переписать.
Конфигурация
Контроллеры объявляются как обычный Spring компоненты в файле dispatcher-servlet.xml. Маршрутизация определяется в этом же файле при помощи класса SimpleUrlHandlerMapping.
Подробно останавливаться на этом не будем (конфигурационный файл и маршрутизация с использованием SimpleUrlHandlerMapping подробно описаны в документации) просто приведём пример файла dispatcher-servlet.xml для контроллеров, которые мы рассмотрели ранее.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version='1.0' encoding='UTF-8' ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="index.htm">indexController</prop> <prop key="home.htm"> homeController</prop> <prop key="multi/index.htm">multiController</prop> <prop key="multi/test.htm">multiController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /> <bean name="indexController" class="org.springframework.web.servlet.mvc.ParameterizableViewController" p:viewName="index" /> <bean name="homeController" class="WebApp1.Controllers.HomeController" p:viewName="home" /> <bean name="multiController" class="WebApp1.Controllers.MultiController" /> </beans> |
Помимо всего остального данный конфигурационный файл должен в обязательном порядке задавать расположение корневой папки с файлами представлений (p:prefix) и их расширение (p:suffix).
Для этого используется компонент viewResolver. Для данного компонента рекомендуется использовать класс InternalResourceViewResolver, который позволяет задействовать в качестве представлений соответствующие файлы проекта.
Ниже приведён пример файла конфигурации сервера приложений (web.xml) применительно к данному случаю.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app> |
Заключение
Мы рассмотрели определение контролеров и маршрутизации в Spring MVC с использованием XML.
Приведённых в статье примеров и комментариев к ним будет вполне достаточно для понимания основ работы подобных проектов и облегчения их создания или доработки.
В завершение приведём два скриншота, которые наглядно проиллюстрируют примерную структуру проекта, построенного в соответствии с рассмотренными принципами.
На первый взгляд сложность организации даже столь простого проекта может смутить. Но, к счастью, существует целый ряд IDE, которые поддерживают Spring и позволяют создавать подобные проекты на основе унифицированных шаблонов. Тем самым освобождая программиста от ручного выполнения рутинных операций.
К слову, NetBeans по умолчанию создаёт для Spring MVC проекты именно такого формата, который был рассмотрен в данной статье (пока «из коробки» поддерживается максимум Spring 4). Только оригинальный шаблон NetBeans немного проще того проекта, который послужил примером для данной статьи.
Но, в любом случае всё это уже «вчерашний день». В одной из следующих статей будет обязательно рассмотрен уже современных подход в разработке web приложений на фреймворке Spring MVC с применением аннотаций.
Добавить комментарий