Spring WebFlux, як і Spring MVC, розроблений за шаблоном єдиної точки входу (front controller), де центральний WebHandler, DispatcherHandler забезпечує загальний алгоритм обробки запитів, а фактична робота виконується конфігурованими компонентами-делегатами. Ця модель є гнучкою і підтримує різні робочі процеси.

DispatcherHandler виявляє необхідні йому компоненти-делегати з конфігурації Spring. Він також розроблений таким чином, щоб виступати в ролі біна Spring, і реалізує ApplicationContextAware для доступу до контексту, в якому він виконується. Якщо DispatcherHandler оголошено з ім'ям біна webHandler, то він, у свою чергу, виявляється WebHttpHandlerBuilder, який збирає ланцюжок обробки запитів.

Конфігурація Spring у додатку на WebFlux зазвичай містить:

  • DispatcherHandler з ім'ям біна webHandler;

  • Біни WebFilter та WebExceptionHandler;

  • Спеціальні біни DispatcherHandler ;

  • Та інше.

Конфігурація передається WebHttpHandlerBuilder для побудови ланцюжка обробки, як показано в наступному прикладі:

Java
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build()
Kotlin
val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()

Отриманий HttpHandler готовий до використання із серверним адаптером.

Спеціалізовані види бінів

DispatcherHandler делегує спеціальним бінам обробку запитів та видачу належних відповідей. Під "спеціальними бінами" ми маємо на увазі керовані Spring екземпляри Object, які реалізують контракти фреймворку WebFlux. Зазвичай вони мають вбудовані контракти, але ти можеш налаштувати їх властивості, розширити їх або замінити. Зверни увагу, що існують також інші типи бінів, що визначаються на нижчому рівні.

Тип біна Пояснення

HandlerMapping

Відображає запит на обробник. Відображення ґрунтується на деяких умовах, деталі яких залежать від реалізації HandlerMapping — анотовані контролери, прості відображення за шаблоном URL-адрес та ін.

Основними реалізаціями HandlerMapping є RequestMappingHandlerMapping для анотованих за допомогою @RequestMapping методів, RouterFunctionMapping для функціональних маршрутів кінцевих точок та SimpleUrlHandlerMapping для явної реєстрації шляхів URI-ідентифікаторів та екземплярів WebHandler.

HandlerAdapter

Допомагає DispatcherHandler викликати обробник, відображений на запит, незалежно від того, як цей обробник буде викликаний фактично. Наприклад, виклик анотованого контролера вимагає дозволу анотацій. Основна мета HandlerAdapter — захистити DispatcherHandler від таких деталей.

HandlerResultHandler

Обробляє результат виклику обробника та завершує відповідь.

Конфігурація WebFlux

Програми можуть оголошувати біни інфраструктури, які необхідні для обробки запитів. Однак у більшості випадків конфігурація WebFlux є найкращою відправною точкою. В ній оголошуються необхідні біни і надається API зворотного виклику конфігурації вищого рівня для налаштування.

Spring Boot покладається на конфигурацію WebFlux для конфігурування Spring WebFlux, а також надає безліч додаткових опцій.

Обробка

DispatcherHandler обробляє запити таким чином:

  • Кожному HandlerMapping пропонується знайти відповідний обробник, і використовується перший збіг.

  • Якщо обробник знайдений, він виконується через відповідний HandlerAdapter, який відкриває значення після виконання у вигляді HandlerResult .

  • HandlerResult передається відповідному HandlerResultHandler для завершення обробки шляхом запису у відповідь безпосередньо або за допомогою подання для візуалізації.

Обробка результатів

Значення, що повертається після виклику обробника через HandlerAdapter, обертається як HandlerResult, разом з деяким додатковим контекстом, і передається першому HandlerResultHandler, який містить твердження про його підтримку. У наступній таблиці показано доступні продажі HandlerResultHandler, всі вони оголошені в конфігурації WebFlux:

Тип обробника результатів Зворотні значення Порядок за замовчуванням

ResponseEntityResultHandler

ResponseEntity, зазвичай з екземплярів анотації @Controller.

0

ServerResponseResultHandler

ServerResponse, зазвичай від функціональних кінцевих точок.

0

ResponseBodyResultHandler

Обробка значень, що повертаються, з методів, позначених анотацією @ResponseBody, або класів, позначених анотацією @RestController.

100

ViewResolutionResultHandler

CharSequence, View, Model, Map, Rendering або будь-який інший Object вважається атрибутом моделі.

Integer.MAX_VALUE

Винятки

HandlerResult, який повертається з HandlerAdapter, може відкривати функцію обробки помилок на основі будь-якого механізму, специфічного для оброблювача. Ця функція помилки викликається, якщо:

  • Виклик обробника (наприклад, анотація @Controller) завершується помилкою.

  • Обробка обробника, що повертається, через HandlerResultHandler завершує помилкою.

Функція помилки може змінити відповідь (наприклад, на статус помилки), за умови, що сигнал помилки виникає до того, як реактивний тип, що повертається обробником, створить будь-які елементи даних.

Так підтримуються методи, анотовані @ExceptionHandler у класах, анотованих @ Controller. На противагу цьому їхня підтримка в Spring MVC побудована на HandlerExceptionResolver. Зазвичай це не відіграє ролі. Однак слід пам'ятати, що у WebFlux не можна використовувати анотацію @ControllerAdvice для обробки винятків, що виникають до вибору обробника.

Див. також підрозділ "Управління винятками" в розділі "Анотований контролер" або підрозділ "Виключення" в розділі, присвяченому API WebHandler.

Розпізнавання подання

Розпізнавання подання дозволяє здійснити візуалізацію в браузері за допомогою HTML-шаблону та моделі, не прив'язуючи тебе до конкретної технології подання. У Spring WebFlux розпізнавання подання підтримується спеціальним HandlerResultHandler, який використовує екземпляри ViewResolver для відображення рядка (що представляє логічне ім'я подання) на екземпляр View. Потім View використовується для візуалізації відповіді.

Обробка

HandlerResult, переданий до ViewResolutionResultHandler, містить значення, що повертається обробником, і модель, що містить атрибути, додані під час обробки запиту. Значення, що повертається обробляється як одне з наступних:

  • String, CharSequence: Логічне ім'я подання, яке має бути дозволене в View через список налаштованих реалізацій ViewResolver.

  • void: Вибирається ім'я подання за замовчуванням на основі шляху запиту, за вирахуванням провідної та подальшої косої риси, і дозволяється у View. Те саме відбувається, якщо не було вказано ім'я подання (наприклад, було повернено атрибут моделі) або є асинхронне значення, що повертається (наприклад, Mono завершилося порожнім).

  • Rendering: API для сценаріїв розпізнавання уявлень. Вивчи можливості вашої IDE за допомогою автодоповнення коду.

  • Model, Map: Додаткові атрибути моделі, які мають бути додані в модель для запиту.

  • Будь-яке інше: Будь-яке інше значення, що повертається (крім простих типів, що визначаються BeanUtils#isSimpleProperty) вважається атрибутом моделі, який має бути доданий до моделі. Ім'я атрибута виводиться з імені класу за допомогою угод, якщо відсутня анотація методу обробника @ModelAttribute.

Модель може містити асинхронні, реактивні типи (наприклад, з Reactor чи RxJava). Перед візуалізацією подання AbstractView дозволяє такі атрибути моделі до конкретних значень та оновлює модель. Однозначні реактивні типи дозволяються в одне або без значення (якщо порожньо), а багатозначні реактивні типи (наприклад, Flux<T>) збираються і дозволяються в List<T>.

Конфігурування розпізнавання уявлень зводиться просто до додавання біна ViewResolutionResultHandler до конфігурації Spring. Конфігурація WebFlux передбачає виділений API конфігурації для розпізнавання уявлень.

Перенаправлення

Спеціальний префікс redirect: в імені подання дозволяє виконати перенаправлення. UrlBasedViewResolver (і підкласи) розпізнає це як вказання на необхідність перенаправлення. Решта імені представлення — це URL-адреса перенаправлення.

Чистий результат такий самий, якби контролер повертав RedirectView або Rendering.redirectTo("abc").build (), але тепер сам контролер може оперувати логічними іменами уявлень. Ім'я подання, таке як redirect:/some/resource, відноситься до поточної програми, в той час як ім'я подання, таке як redirect:https://example.com/arbitrary/path, перенаправляє на абсолютну URL-адресу.

Узгодження вмісту

ViewResolutionResultHandler підтримує узгодження вмісту. Цей обробник порівнює типи середовища передачі даних запиту з типами середовища передачі даних, які підтримуються кожним вибраним View. Використовується перший же View, який підтримує запитаний тип(и) середовища передачі даних.

Для підтримки таких типів середовища передачі даних, як JSON та XML, Spring WebFlux передбачає HttpMessageWriterView, яке є спеціальним View, що здійснює візуалізацію через HttpMessageWriter. Зазвичай ці подання конфігуруються як подання за умовчанням через конфігурацію WebFlux. Подання за замовчуванням завжди обираються та використовуються, якщо відповідають запитаному типу середовища передачі даних.