Тема 36. Spring MVC - BelyiZ/JavaCourses GitHub Wiki

Содержание:

  1. Паттерн MVC
  2. Dispatcher Servlet
  3. Spring-контроллеры
  4. Шаблонизаторы
  5. Обзор и подключение Swagger
  6. Обработка ошибок
  7. Список литературы/курсов

Паттерн MVC

Статическая страница на HTML не умеет реагировать на действия пользователя. Для двухстороннего взаимодействия нужны динамические веб-страницы. MVC — ключ к пониманию разработки динамических веб-приложений, поэтому разработчику обязательно нужно знать эту модель.

Фреймворк Spring MVC обеспечивает архитектуру паттерна Model — View — Controller (Модель — Отображение (далее — Вид) — Контроллер) при помощи слабо связанных готовых компонентов. Это способ организации кода, который предполагает выделение блоков, отвечающих за решение разных задач. Один блок отвечает за данные приложения, другой отвечает за внешний вид, а третий контролирует работу приложения.

Компоненты MVC:

Модель (model) — этот компонент отвечает за данные, а также определяет структуру приложения. Model инкапсулирует (объединяет) данные приложения, в целом они будут состоять из POJO («Старых добрых Java-объектов», или бинов). Например, если необходимо создать To-Do приложение, код компонента model будет определять список задач и отдельные задачи. Это самая независимая часть системы. Настолько независимая, что она не должна ничего знать о модулях Вид и Контроллер.

Представление (view) — этот компонент отвечает за взаимодействие с пользователем. То есть код компонента view определяет внешний вид приложения и способы его использования. Основное предназначение Представления — предоставлять информацию из Модели в удобном для восприятия пользователя формате, как правило, генерируя HTML, которые мы видим в своём браузере. Основное ограничение Представления — он никак не должен изменять Модель.

Контроллер (controller) — этот компонент отвечает за связь между model и view. Код компонента controller определяет, как сайт реагирует на действия пользователя. По сути, это мозг MVC-приложения. Основное предназначение Контроллера — обрабатывать действия пользователя. Именно через Контроллер пользователь вносит изменения в Модель. Точнее в данные, которые хранятся в Модели.

Dispatcher Servlet

Как мы говорили ранее вся логика работы Spring MVC построена вокруг DispatcherServlet, который принимает и обрабатывает все HTTP-запросы (из UI) и ответы на них. Рабочий процесс обработки запроса DispatcherServlet'ом проиллюстрирован на схеме:

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

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

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

Разберем паттерн MVC на примере магазина сэндвичей.

Представьте, что вы пришли в магазин или кафе, где можно заказать сэндвич. В меню есть бутерброды с тунцом, индейкой и ветчиной. Вы заказываете сэндвич с индейкой.

Продавец или бармен с полуслова понимает вас. Он поворачивается в сторону кухни и говорит поварам, чтобы они приготовили сэндвич с индейкой.

У поваров под рукой есть разные продукты: тунец, индейка, ветчина, сыр, листья салата и другие ингредиенты, которые добавляют в бутерброды. Они выбирают только то, что нужно для вашего сэндвича с индейкой. Вы получаете свой заказ.

Покупку бутерброда можно описать через MVC:

Модель: кухня, на которой повар делает сэндвич. Представление: готовый бутерброд, который вы с удовольствием едите. Контроллер: продавец или бармен, который принимает заказ и передаёт его на кухню.

Из всего этого можно сделать вполне логичный вывод. Сложную систему нужно разбивать на модули.

Рассмотрим пример:

Ключевая идея MVC состоит в том, что любое приложение с пользовательским интерфейсом в первом приближении можно разбить на 2 модуля: модуль, отвечающий за реализацию бизнес-логики приложения, и пользовательский интерфейс.

В первом модуле будет реализован основной функционал приложения. Данный модуль будет ядром системы, в котором реализуется Модель предметной области приложения. В концепции MVC данный модуль будет Моделью.

Во втором модуле будет реализован весь пользовательский интерфейс, включая отображение данных пользователю и логику взаимодействия пользователя с приложением.

Основная цель такого разделения — сделать так, чтобы ядро системы (Модель в терминологии MVC) могла независимо разрабатываться и тестироваться.

Архитектура приложения после подобного разделения будет выглядеть следующим образом:

Далее необходимо используя шаблон Наблюдатель, добиться еще большей независимости Модели, а также синхронизации пользовательских интерфейсов.

Здесь мы преследуем 2 цели:

  • Добиться еще большей независимости Модели.
  • Синхронизировать пользовательские интерфейсы.

Понять, что подразумевается под синхронизацией пользовательских интерфейсов, поможет следующий пример.

Предположим, мы покупаем билет в кино через интернет и видим количество свободных мест в кинотеатре. Одновременно с нами покупать билет в кино может кто-то еще. Если этот кто-то купит билет раньше нас, нам бы хотелось увидеть, что количество свободных мест на наш сеанс уменьшилось.

А теперь поразмышляем о том, как это может быть реализовано внутри программы. Предположим, у нас есть ядро системы (Модель) и интерфейс (веб страница, на которой осуществляем покупку).

На сайте 2 пользователя одновременно выбирают место.

Первый пользователь купил билет. Второму пользователю необходимо отобразить на странице эту информацию.

Как это происходит:

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

Чтобы достичь этого, необходимо реализовать шаблон Наблюдатель. С его помощью Модель рассылает уведомления об изменениях всем подписчикам. Интерфейс, являясь таким подписчиком, получит уведомление и обновится.

Шаблон Наблюдатель позволяет Модели с одной стороны информировать интерфейс (представление и контроллер) о том, что в ней произошли изменения, а с другой — фактически ничего о них “не знать”, и тем самым оставаться независимой. С другой стороны, это позволит синхронизировать пользовательские интерфейсы.

Разделение интерфейса на Представление и Контроллер Продолжаем делить приложение на модули, но уже на более низком уровне иерархии. На этом шаге пользовательский интерфейс (который был выделен в отдельный модуль на шаге 1) делится на Представление и Контроллер.

Сложно провести строгую черту между Представлением и Контроллером. Если говорить о том, что Представление — это то, что видит пользователь, а Контроллер — это механизм, благодаря которому пользователь может взаимодействовать с системой, можно обнаружить некоторое противоречие.

Элементы управления, например, кнопки на веб-странице или виртуальная клавиатура на экране телефона, это по сути часть Контроллера. Но они так же видны пользователю, как и любая часть Представления.

Здесь скорее речь идет о функциональном разделении. Основная задача пользовательского интерфейса — обеспечить взаимодействие пользователя с системой. Это означает, что у интерфейса всего 2 функции:

  • выводить и удобно отображать пользователю информацию о системе;
  • вводить данные и команды пользователя в систему (передавать их системе);

Данные функции и определяют то, как нужно делить интерфейс на модули.

В итоге, архитектура системы выглядит так:

Итак, у нас появилось приложение из трех модулей, которые называются Модель, Представление и Контроллер.

Таким образом:

  1. Следуя принципам MVC, систему нужно разделять на модули.
  2. Самым важным и независимым модулем должна быть Модель.
  3. Модель — ядро системы. Нужна возможность разрабатывать и тестировать ее независимо от интерфейса. Для этого на первом шаге сегрегации системы нужно разделить ее на модель и интерфейс. Далее, с помощью шаблона Наблюдатель, укрепляем модель в ее независимости и получаем синхронизацию пользовательских интерфейсов. Третьим шагом делим интерфейс на Контроллер и Представление. Все, что на ввод информации от пользователя в систему — это в Контроллер. Все что на вывод информации от системы к пользователю — это в Представление.

Взаимосвязь Представления и Контроллера с Моделью Когда пользователь вводит информацию через Контроллер, он тем самым вносит изменения в модель. По крайней мере, пользователь вносит изменения в данные Модели.

Когда пользователь получает информацию через элементы интерфейса (через Представление), пользователь получает информацию о данных модели.

Как это происходит? Посредством чего Представление и Контроллер взаимодействуют с Моделью? Ведь не может быть так, что классы Представления напрямую используют методы классов Модели для чтения/записи данных, иначе ни о какой независимости Модели не может быть и речи.

Модель представляет тесно связанный между собой набор классов, к которым, по-хорошему, ни у Представления, ни у Контроллера не должно быть доступа.

Для связи Модели с Представлением и Контроллером необходимо реализовать шаблон проектирования Фасад. Фасад Модели будет той самой прослойкой между Моделью и интерфейсом, через которую Представление получает данные в удобном формате, а Контроллер изменяет данные, вызывая нужные методы фасада.

Схематично, в итоге, все будет выглядеть так:

Приведем пример как создавать Controller, Model и View на практике.

Жизненный цикл запроса Как мы говорили ранее 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 и последующего отображения результата конечному пользователю.

Конфигурирование

Шаги по реализации веб-приложения 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>

Определение Контроллера Разберем пример с применением нескольких распространенных аннотаций 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-запросов.

Создание вида (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>

Преимущества MVC

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

Шаблонизаторы

Шаблонизаторы являются отличным инструментом для создания веб-приложений с более чистым и простым кодом. Рассмотрим наиболее популярные.

Mustache.JS Mustache.JS - это логический шаблонный синтаксис. Его можно использовать для HTML, конфигурационных файлов, исходного кода - чего угодно. Он работает путем расширения тегов в шаблоне, используя значения, предоставленные в хэше или объекте.

Transparency Transparency - это минимальный шаблонизатор для jQuery. Он отображает объекты JSON на элементы DOM с нулевой конфигурацией. Просто вызовите .render().

Hogan.js Hogan.js - это шаблонизатор JS 3.4k, разработанный в Twitter. Используйте его как часть вашего упаковщика ресурсов для предварительной компиляции шаблонов или включите его в браузер для обработки динамических шаблонов. Если вы разрабатываете с Node.js, просто используйте NPM, чтобы добавить пакет Hogan.

HandlebarsJS HandlebarsJS - обеспечивает необходимую мощность, позволяющую эффективно создавать семантические шаблоны без каких-либо разочарований. Handlebars в значительной степени совместим с шаблонами Mustache. В большинстве случаев можно поменять Mustache с помощью Handlebars и продолжить использовать текущие шаблоны.

Jade Language Jade - это движок HTML шаблонов, в основном используемый для серверных шаблонов в NodeJS.

Nunjucks Nunjucks - это богатый и мощный язык шаблонов с наследованием блоков, автоэкранированием, макросами, асинхронным управлением и многим другим.

Обзор и подключение Swagger

Swagger - это стандартизированная и полная структура для генерации, описания, вызова и визуализации веб-сервисов RESTful. Это удобный инструмент для создания документации API, который помогает разработчикам сэкономить время. Он предлагает несколько решений для интеграции в проект и формирования интерактивной версии документации, с которой будет удобно взаимодействовать другим разработчикам, внешним пользователям, клиентам.

Swagger — это набор инструментов, которые помогают описывать API. Благодаря ему пользователи и машины лучше понимают возможности REST API без доступа к коду. С помощью Swagger можно быстро создать документацию и отправить ее другим разработчикам или клиентам.

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

Основные подходы Swagger предлагает два основных подхода к генерированию документации:

  • Автогенерация на основе кода.
  • Самостоятельная разметка-написание.

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

Чтобы пользоваться вторым подходом, нужно знать синтаксис Swagger. Описания можно готовить в формате YAML/JSON. Можно упростить эту задачу, используя Swagger Editor. Конечно, второй подход позволяет сделать документацию более качественной и кастомной для каждого конкретного проекта и его особенностей, к тому же все не так сложно как может показаться, это потребует минимальных дополнительных усилий.

Swagger Core Это Java-реализация спецификации. Для ее использования потребуется:

  • Java 8 и выше
  • Apache Maven 3.0.4 и выше
  • Jackson 2.4.5 и выше

Для его внедрения в проект используются две зависимости.

Приведем примеры:

<dependency>
    <groupId>io.swagger.core.v3</groupId>
    <artifactId>swagger-annotations</artifactId>
    <version>2.1.11</version>
</dependency>
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.5.2</version>
</dependency>
Другой способнастроить maven-плагин. Тогда описания при сборке проекта будут генерироваться в файл YAML. Пример:

<plugin>
 <groupId>org.springdoc</groupId>
 <artifactId>springdoc-openapi-maven-plugin</artifactId>
 <version>0.3</version>
 <executions>
   <execution>
   <phase>integration-test</phase>
   <goals>
     <goal>generate</goal>
   </goals>
   </execution>
 </executions>
 <configuration>
   <apiDocsUrl>http://localhost:3080/v3/api-docs</apiDocsUrl>
   <outputFileName>openapi.yaml</outputFileName>
   <outputDir>${project.build.directory}</outputDir>
 </configuration>
</plugin>

Для конфигурации нужны еще два бина (beans). В них мы описываем название приложения, версию API, добавляем другие важные данные.

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

Аннотация Использование
@Operation Для описания операции или метода HTTP
@Parameter Для представления одного параметра в операции
@RequestBody Для представления тела запроса в операции
@ApiResponse Для представления тела ответа в операции
@Tag Для представления тегов операции или определения OpenAPI
@Server Для представления серверов операции или определения OpenAPI
@Callback Для описания набора запросов
@Link Для представления ссылки времени разработки для ответа
@Schema Для определения входных и выходных данных
@ArraySchema Для определения входных и выходных данных для типов массивов
@Content Для представления схемы и примеров для мультимедиа
@Hidden Для скрытия ресурса, операции или свойстваSwagger Codegen

Преимущества Swagger Codegen:

  • Генерирование серверов — позволяет избавиться от рутины, создавая шаблонный код на 20+ языках.
  • Упрощенное генерирование SDK — можно создавать клиентские наборы на 40+ языках для быстрой интеграции с вашим API.
  • Постоянное обновление инструментов.

Чтобы добавить Swagger Codegen в проект, используйте зависимость:

<dependency>
    <groupId>io.swagger.codegen.v3</groupId>
    <artifactId>swagger-codegen-maven-plugin</artifactId>
    <version>3.0.24</version>
</dependency>
Как и в случае с Swagger Core, можно настроить maven-плагин для генерации клиента или мок-сервера.

<plugin>
        <groupId>org.openapitools</groupId>
        <artifactId>openapi-generator-maven-plugin</artifactId>
        <version>3.3.4</version>
        <executions>
          <execution>
            <phase>compile</phase>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <generatorName>spring</generatorName>
              <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
              <output>${project.build.directory}/generated-sources</output>
              <apiPackage>com.api</apiPackage>
              <modelPackage>com.model</modelPackage>
              <supportingFilesToGenerate>
                ApiUtil.java
              </supportingFilesToGenerate>
              <configOptions>
                <groupId>${project.groupId}</groupId>
                <artifactId>${project.artifactId}</artifactId>
                <artifactVersion>${project.version}</artifactVersion>
                <delegatePattern>true</delegatePattern>
                <sourceFolder>swagger</sourceFolder>
                <library>spring-mvc</library>
                <interfaceOnly>true</interfaceOnly>
                <useBeanValidation>true</useBeanValidation>
                <dateLibrary>java8</dateLibrary>
                <java8>true</java8>
              </configOptions>
              <ignoreFileOverride>${project.basedir}/.openapi-generator-ignore</ignoreFileOverride>
            </configuration>
          </execution>
        </executions>
      </plugin>

Swagger Codegen предоставляет следующие команды:

  • Config-help — помощь с настройкой выбранного языка.
  • Generate — генерирование кода с выбранным генератором.
  • Help — вывод справочной информации про openapi-generator.
  • List — список доступных генераторов.
  • Meta — генератор набора шаблонов и настроек Codegen. Использует информацию о выбранном языке.
  • Validate — проверка спецификации.
  • Version — отображение используемой версии.
  • Самые полезные команды — generate и validate. Первая позволяет создать клиент, а вторая — проверить его соответствие спецификации.
  • Посмотреть полный список возможностей можно с помощью команды help после запуска jar-файла.

Swagger UI Swagger UI визуализирует ресурсы OpenAPI и взаимодействие с ними без отображения логики реализации. Этот инструмент берет спецификацию и превращает ее в интерактивный проект, где можно выполнять разные запросы для тестирования API.

Преимущества Swagger UI:

  • Нет зависимостей. Интерфейс доступен в любой среде разработки.
  • Полная поддержка браузерами. Удобное взаимодействие для других разработчиков и клиентов. Можно проверить все операции, предоставляемые API, даже не имея специальных знаний.
  • Простая навигация. Ресурсы и конечные точки представлены в виде аккуратно распределенного на категории списка.
  • Можно настраивать стиль и пользовательский интерфейс так, как вам хочется.
  • Пользовательский интерфейс Swagger полностью размещен в SwaggerHub. Вы можете написать и визуализировать API или импортировать существующие определения для создания интерактивного интерфейса, размещенного в облаке. Благодаря встроенной интерактивности SwaggerHub позволяет безопасно предоставлять доступ к документации внешним пользователям или другим разработчикам.

Swagger Editor Это онлайн-редактор для изменения и проверки API внутри браузера. Позволяет просматривать документацию в реалтайме. С его помощью можно создать описания, а затем использовать их с полным набором инструментов для генерации документации.

ПреимуществаSwagger Editor:

  • Работает в любой среде разработки, локально и в сети.
  • Дает обратную связь — показывает ошибки в синтаксисе по мере написания, проверяя его на соответствие OpenAPI.
  • Позволяет мгновенно визуализировать API через Swagger UI.
  • Помогает писать документацию быстрее благодаря интеллектуальному автозаполнению.
  • Предоставляет гибкие инструменты для настройки конфигурации — от темы оформления до межстрочного интервала.
  • Предлагает создание серверных заглушек и клиентских библиотек для вашего API на всех популярных языках.

Преимущества использования Swagger

  • Swagger может создать интерактивную консоль API, которую разработчики могут использовать для быстрого изучения и опробования API.
  • Swagger может генерировать клиентский SDK-код для реализации на различных платформах.
  • Файлы Swagger могут автоматически генерироваться из комментариев кода на многих различных платформах.
  • Swagger имеет сильное сообщество со многими влиятельными участниками.

Обработка ошибок

Самый простой способ обработки ошибок-это ответить соответствующим кодом состояния.

Некоторые распространенные коды ответов включают в себя:

  • 400 Плохой запрос — Клиент отправил недопустимый запрос — например, отсутствует требуемое тело запроса или параметр.

  • 401 Неавторизованный — Клиенту не удалось пройти аутентификацию на сервере.

  • 403 Forbidden — Клиент аутентифицирован, но не имеет разрешения на доступ к запрошенному ресурсу.

  • 404 Не найден — Запрошенный ресурс не существует.

  • 412 Ошибка предварительного условия — одно или несколько условий в полях заголовка запроса оцениваются как ложные.

  • 500 Внутренняя ошибка сервера — На сервере произошла общая ошибка.

  • 503 Услуга Недоступна — Запрошенная услуга недоступна.

  • Будучи базовыми, эти коды позволяют клиенту понять широкий характер возникшей ошибки. Например, мы знаем, если получаем ошибку 403, что у нас нет разрешений на доступ к запрошенному ресурсу.

Во многих случаях, однако, необходимо предоставить дополнительные детали в наших ответах.

500 ошибок сигнализируют о том, что при обработке запроса на сервере возникли некоторые проблемы или исключения. Как правило, эта внутренняя ошибка не является делом нашего клиента.

Следовательно, чтобы свести к минимуму такого рода ответы клиенту, мы должны усердно пытаться обрабатывать или улавливать внутренние ошибки и отвечать другими соответствующими кодами состояния, где это возможно. Например, если исключение возникает из-за того, что запрошенный ресурс не существует, мы должны выставить это как ошибку 404, а не 500.

Это не означает, что 500 никогда не должны быть возвращены, только то, что он должен использоваться для непредвиденных условий – таких как отключение службы – которые мешают серверу выполнить запрос.

Список литературы/курсов

  1. http://leonidas.github.io/transparency/
  2. http://twitter.github.io/hogan.js/
  3. https://handlebarsjs.com/
  4. https://jade-lang.com/
  5. http://mozilla.github.io/nunjucks/

Тема 35. HTTP и REST|Оглавление|Тема 37. Spring Data JPA

⚠️ **GitHub.com Fallback** ⚠️