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

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.

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

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

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023