Рубріки: Теория

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 — возможность менять один из компонентов приложения, существенно не влияя на остальные.

Кратко пройдемся по каждому из них:

  1. Модель. Модель содержит данные приложения. Обычно включает в себя POJO-классы (Plain Old Java Objects ) — простые старые Java-объекты или по-другому — бины.
  2. Представление или вид. Используется для визуализации и отображения данных приложения при помощи пользовательского интерфейса например JSP. Отвечает за то, как будут выглядеть данные модели в браузере пользователя.
  3. Контроллер. Контроллер нужен для обработки пользовательских запросов и вызова серверных служб. Он структурирует запрос, создает соответствующую модель для дальнейшего отображения ее в браузере.

2. DispatcherServlet

Dispatcher Servlet — сердце Spring Web MVC, полностью настраиваемый фронт-контроллер, координирующий все действия по обработке запросов аналог Struts ActionServlet / JSF FacesServlet:

Это типичный шаблон дизайна при разработке веб-приложений, распределяющий запросы пользователя и управляющий работой других компонентов приложения, отсылая команды каждому конкретному контроллеру Spring MVC. Он отвечает за инициализацию интерфейса WebApplicationContext, загружая конфигурацию относящуюся к веб-компонентам.

3. Жизненный цикл запроса

Как мы уже с вами разобрались, Spring MVC Framework логически построен на основе фронт-контроллера DispatcherServlet, обрабатывающего все HTTP-запросы и ответы. Чтобы лучше понять как он работает, посмотрим, как все устроено изнутри:

Источник: java2blog.com

Принцип его работы показан на изображении выше, каждый шаг промаркирован, давайте разберем все поэтапно:

  • Фронт-контроллер 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

Собирая все вместе, подведем итоги:

  1. Легковесность: поскольку Spring — это легкий фреймворк, в веб-приложении на основе Spring не будет проблем с производительностью.
  2. Высокая продуктивность: Spring MVC может ускорить любой процесс разработки.
  3. Безопасность: большинство веб-приложений для онлайн-банкинга разрабатывается с использованием Spring MVC, что дает выгоду за счет встроенного Spring Security — отличного API для реализации безопасности корпоративного уровня.
  4. Поддерживается паттерн MVC: поэтому это отличный способ разработки модульных веб-приложений.
  5. Spring MVC также реализует все основные функции ядра Spring Framework, среди которых популярные Inversion of Control (инверсия управления) и Dependency Injection (внедрение зависимостей).

7. Пример реализации фреймворка Spring MVC

Чтобы досконально разобраться с рассматриваемой концепцией, предлагаю ознакомиться с примерами реализации фреймворка из общедоступных источников:

  1. Базовый пример реализации программы Hello World на Spring 4 (XML-конфигурация).
  2. Примеры MVC приложений на Spring, выложенные на GitHub.
  3. Еще один простой пример приложения на Spring MVC.

Ну а если вам лучше один раз посмотреть и послушать, чем десять раз прочитать — несколько ссылок на обучающие видеоролики по теме:

Останні статті

Что такое прокси-сервер: пояснение простыми словами, зачем нужны прокси

Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…

21.11.2024

Что такое PWA приложение? Зачем необходимо прогрессивное веб-приложение

Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…

19.11.2024

Как создать игру на телефоне: программирование с помощью конструктора

Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…

17.11.2024

Google Bard: эффективный аналог ChatGPT

В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…

14.11.2024

Скрипт и программирование: что это такое простыми словами

Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…

12.11.2024

Дедлайн в разработке: что это такое простыми словами

Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…

11.11.2024