Spring MVC — основные понятия и архитектура
В статье рассмотрим основные принципы взаимодействия популярного Java-фреймворка Spring и базового паттерна разработки MVC. Это отличное введение для новичка в практику использования Spring в современном программировании.
Содержание:
1. Что такое Spring MVC?
2. DispatcherServlet
3. Жизненный цикл запроса
4. Конфигурирование
5. Определение Контроллера
6. Создание вида (JSP)
7. Пример реализации фреймворка Spring MVC
1. Что такое Spring MVC?
Spring MVC — структура для создания слабо связанных веб-приложений, разделяющая основные аспекты их разработки: объекты, бизнес-логику и внешний вид программы. Основное преимущество архитектуры MVC — возможность менять один из компонентов приложения, существенно не влияя на остальные.
Кратко пройдемся по каждому из них:
- Модель. Модель содержит данные приложения. Обычно включает в себя
POJO
-классы (Plain Old Java Objects ) — простые старые Java-объекты или по-другому — бины. - Представление или вид. Используется для визуализации и отображения данных приложения при помощи пользовательского интерфейса например JSP. Отвечает за то, как будут выглядеть данные модели в браузере пользователя.
- Контроллер. Контроллер нужен для обработки пользовательских запросов и вызова серверных служб. Он структурирует запрос, создает соответствующую модель для дальнейшего отображения ее в браузере.
2. DispatcherServlet
Dispatcher Servlet — сердце Spring Web MVC, полностью настраиваемый фронт-контроллер, координирующий все действия по обработке запросов аналог Struts ActionServlet / JSF FacesServlet:
Это типичный шаблон дизайна при разработке веб-приложений, распределяющий запросы пользователя и управляющий работой других компонентов приложения, отсылая команды каждому конкретному контроллеру Spring MVC. Он отвечает за инициализацию интерфейса WebApplicationContext
, загружая конфигурацию относящуюся к веб-компонентам.
3. Жизненный цикл запроса
Как мы уже с вами разобрались, Spring MVC Framework логически построен на основе фронт-контроллера DispatcherServlet
, обрабатывающего все HTTP-запросы и ответы. Чтобы лучше понять как он работает, посмотрим, как все устроено изнутри:
Принцип его работы показан на изображении выше, каждый шаг промаркирован, давайте разберем все поэтапно:
- Фронт-контроллер
DispatcherServlet
получает запрос. DispatcherServlet
передает этот запросHandlerMapping
— интерфейсу, реализуемому объектами, определяющими отображение (маппинг) между запросами для поиска подходящего контроллера.HandlerMapping
отправляет сведения о контроллере назад вDispatcherServlet
.DispatcherServlet
вызывает контроллер, ранее идентифицированный черезHandlerMapping
. Выбранный контроллер обрабатывает запрос, вызвав соответствующий метод для подготовки данных и создав некую бизнес-логику (или напрямую извлекает информацию из базы данных).- Контроллер возвращает
DispatcherServlet
необходимые данные модели и информацию по UI для подбора внешнего вида их отображения. - Как только
DispatcherServlet
получает объектModelAndView
, он передает егоViewResolver
— интерфейсу, способному находить (резолвить) вид по его имени (View Name
), чтобы затем найти соответствующий вариант отображенияView
. - Определившись с выбором,
ViewResolver
отправляет нужные сведения обратно фронт-контроллеру. DispatcherServlet
вызывает соответствующийView
(определенныйViewResolver
).View
создает отклик в виде HTML-кода и отправляет его назад.- В конце главный контроллер предоставляет инструкции браузеру для настройки данного HTML и последующего отображения результата конечному пользователю.
4. Конфигурирование
Шаги по реализации веб-приложения MVC Spring с использованием Java-конфигурирования:
Шаг 1. Первоначально нам нужно создать файл POM.XML
, содержащий в себе зависимости maven из фреймворка Spring. Он нам пригодится по ходу проекта:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>today.highload</groupId> <artifactId>SpringMVCjava</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>SpringMVCjava Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.12.RELEASE</version> </dependency> </dependencies> <build> <finalName>SpringMVCjava</finalName> </build> </project>
Шаг 2: Проект должен содержать файл web.xml
, получающий все запросы от клиента. В нашем случае вместо web.xml
мы будем использовать WebInitializer.java
. Функция getServletMappings()
принимает все запросы, соответствующие сопоставлению URL-адресов '/'
.
Функция getServletConfigClasses()
настраивает файл MVCconfig.java
, который мы будем использовать вместо сервлета-диспетчера для java-конфигурирования. Этот класс расширяет класс AbstractAnotationConfigDispatcherServletInitializer
и служит целям, ранее прописанным нами в файле web.xml
. Этот файл определяется так:
package today.highload.web; import org.springframework.web .servlet.support .AbstractAnotationConfigDispatcherServletInitializer; public class WebInitializer extends AbstractAnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { // TODO Auto-generated method stub return null; } @Override protected Class<?>[] getServletConfigClasses() { // TODO Auto-generated method stub return new Class[] { MVCconfig.class }; } @Override protected String[] getServletMappings() { // TODO Auto-generated method stub return new String[] { "/" }; } }
Комментарий // TODO Auto-generated method stub автоматически вставляется системой, напоминая разработчику о том, что далее нужно реализовать в этих методах какую-нибудь логику иначе почему они должны существовать?.
Шаг 3. Теперь нам нужно создать файл MVCconfig.java
. Как уже упоминалось выше, мы будем использовать его вместо DispatcherServlet
. Аннотирование класса с помощью @Configuration
указывает, что класс может использоваться контейнером Spring IoC
в качестве источника определений bean
-компонентов.
Чтобы включить автоопределение аннотированных контроллеров, необходимо добавить в конфигурацию сканирование компонентов. Он также дает путь к базовому пакету (например, today.highload.web
) в котором нужно искать файлы контроллера. Этот класс расширяет класс WebMvcConfigurerAdapter
для обслуживания сервлета диспетчера.
package today.highload.web; import org.springframework.context .annotation.ComponentScan; import org.springframework.context .annotation.Configuration; import org.springframework.web.servlet .config.annotation .WebMvcConfigurerAdapter; @Configuration @ComponentScan ({"today.highload.web"}) public class MVCconfig extends WebMvcConfigurerAdapter { }
Шаг 4: Теперь нам нужно определить контроллер. Контроллеры интерпретируют вводимые пользователем данные и преобразуют их в модель.
Аннотации в стиле @RequestMapping
используются для отображения URL-адреса (например /GREET
для целого класса) или конкретного метода обработчика. Создадим объект класса ModelAndView
, где setViewName ()
указывает вызываемое отображение информации, а addObject ()
указывает динамическое содержимое, добавляемое к этому объекту:
package today.highload.web; import org.springframework .stereotype.Controller; import org.springframework.web .bind.annotation.RequestMapping; import org.springframework.web .servlet.ModelAndView; @Controller public class GreetController { @RequestMapping("/greet") public ModelAndView showview() { ModelAndView mv = new ModelAndView(); mv.setViewName("result.jsp"); mv.addObject("result", "Highload Welcomes " + "you to Spring!"); return mv; } }
Шаг 5: Теперь нам нужно создать индексную страницу index.jsp
для приложения, отображаемую при переходе по заданному URL-адресу:
<html> <body> <h2>Welcome</h2> <form action="greet"> <input type="submit" value="Press to greet"> </form> </body> </html>
Шаг 6: При нажатии кнопки приветствия из указанного выше index.jsp
открывается страница Result.jsp
, которую нам надо предварительно определить вот так:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>Insert title here</title> </head> <body> <h1>${result}</h1> </body> </html>
5. Определение Контроллера
Разберем пример с применением нескольких распространенных аннотаций Spring MVC при отправлении запроса контроллерам от сервлета-диспетчера.
@Controller @RequestMapping("/welcome") public class WelcomeController { @RequestMapping(method = RequestMethod.GET) public String printWelcome(ModelMap model) { model.addAttribute("message", "Welcome to SpringMVC"); return "Welcome"; } }
Аннотация @Controller
говорит о том, что класс является контроллером Spring MVC. Аннотация @RequestMapping
нужна для маппинга (связывания) с URL класса или конкретного метода обработчика.
Причем, в первом случае она информирует нас о принадлежности всех методов в рассматриваемом контроллере, конкретно — к URL-адресу “/Welcome
“. Во втором случае с помощью @RequestMapping
мы объявляем метод printWelcome()
, определяя его как метод по умолчанию для обработки HTTP-запросов.
6. Создание вида (JSP)
Используя фреймворк Spring MVC, отобразить страницу можно в десятках разных форматов, в числе которых — JSP, HTML, PDF, Excel, XML, Velocity templates, XSLT, JSON, каналы Atom и RSS, JasperReports и другие. Однако чаще всего применяются шаблоны JSP, написанные при помощи JSTL:
<html> <head> <title>Welcome to MVC</title> </head> <body> <h2>${message}</h2> </body> </html>
Преимущества Spring MVC
Собирая все вместе, подведем итоги:
- Легковесность: поскольку Spring — это легкий фреймворк, в веб-приложении на основе Spring не будет проблем с производительностью.
- Высокая продуктивность: Spring MVC может ускорить любой процесс разработки.
- Безопасность: большинство веб-приложений для онлайн-банкинга разрабатывается с использованием Spring MVC, что дает выгоду за счет встроенного Spring Security — отличного API для реализации безопасности корпоративного уровня.
- Поддерживается паттерн MVC: поэтому это отличный способ разработки модульных веб-приложений.
- Spring MVC также реализует все основные функции ядра Spring Framework, среди которых популярные Inversion of Control (инверсия управления) и Dependency Injection (внедрение зависимостей).
7. Пример реализации фреймворка Spring MVC
Чтобы досконально разобраться с рассматриваемой концепцией, предлагаю ознакомиться с примерами реализации фреймворка из общедоступных источников:
- Базовый пример реализации программы Hello World на Spring 4 (XML-конфигурация).
- Примеры MVC приложений на Spring, выложенные на GitHub.
- Еще один простой пример приложения на Spring MVC.
Ну а если вам лучше один раз посмотреть и послушать, чем десять раз прочитать — несколько ссылок на обучающие видеоролики по теме:
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: