DispatcherHandler
Spring WebFlux 與 Spring MVC 類似,是圍繞前端控制器模式設計的,其中中央 WebHandler
,即 DispatcherHandler
,為請求處理提供共用演算法,而實際工作由可組態的委派元件執行。此模型非常彈性,並支援多樣的工作流程。
DispatcherHandler
從 Spring 組態中探索其所需的委派元件。它也被設計為 Spring Bean 本身,並實作 ApplicationContextAware
以存取其執行的 Context。如果 DispatcherHandler
以 webHandler
的 Bean 名稱宣告,則它會反過來被 WebHttpHandlerBuilder
探索,後者會將請求處理鏈組裝在一起,如 WebHandler
API 中所述。
WebFlux 應用程式中的 Spring 組態通常包含
-
Bean 名稱為
webHandler
的DispatcherHandler
-
WebFilter
與WebExceptionHandler
Bean -
其他
組態會提供給 WebHttpHandlerBuilder
以建構處理鏈,如下列範例所示
-
Java
-
Kotlin
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();
val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()
產生的 HttpHandler
即可與 伺服器配接器 一起使用。
特殊 Bean 類型
DispatcherHandler
委派給特殊 Bean 以處理請求並呈現適當的回應。「特殊 Bean」指的是實作 WebFlux 框架契約的 Spring 管理 Object
實例。這些實例通常帶有內建契約,但您可以自訂其屬性、擴充或替換它們。
下表列出 DispatcherHandler
偵測到的特殊 Bean。請注意,在較低層級也偵測到其他一些 Bean(請參閱 Web Handler API 中的 特殊 Bean 類型)。
Bean 類型 | 說明 |
---|---|
|
將請求對映至處理器。對映基於某些準則,詳細資訊因 主要的 |
|
協助 |
|
處理處理器呼叫的結果並完成回應。請參閱 結果處理。 |
WebFlux 組態
應用程式可以宣告處理請求所需的基础設施 Bean(列在 Web Handler API 和 DispatcherHandler
下)。但是,在大多數情況下,WebFlux 組態 是最佳起點。它宣告了所需的 Bean,並提供更高等級的組態回呼 API 來自訂它。
Spring Boot 依賴 WebFlux 組態來組態 Spring WebFlux,並提供許多額外的便利選項。 |
處理
DispatcherHandler
依循以下步驟處理請求
-
每個
HandlerMapping
都會被要求尋找符合的處理器,並使用第一個符合的處理器。 -
如果找到處理器,則會透過適當的
HandlerAdapter
執行,後者會將執行的傳回值公開為HandlerResult
。 -
HandlerResult
會被提供給適當的HandlerResultHandler
,以透過直接寫入回應或使用視圖呈現來完成處理。
結果處理
透過 HandlerAdapter
呼叫處理器的傳回值會被包裝為 HandlerResult
,連同一些額外的 Context,並傳遞給第一個聲稱支援它的 HandlerResultHandler
。下表顯示可用的 HandlerResultHandler
實作,所有這些實作都在 WebFlux 組態 中宣告
結果處理器類型 | 傳回值 | 預設順序 |
---|---|---|
|
|
0 |
|
|
0 |
|
處理來自 |
100 |
|
另請參閱 視圖解析。 |
|
例外
HandlerAdapter
實作可以內部處理從呼叫請求處理器(例如控制器方法)產生的例外。但是,如果請求處理器傳回非同步值,則例外可能會被延遲。
HandlerAdapter
可以將其例外處理機制公開為設定在它傳回的 HandlerResult
上的 DispatchExceptionHandler
。當設定時,DispatcherHandler
也會將其應用於結果的處理。
HandlerAdapter
也可選擇實作 DispatchExceptionHandler
。在這種情況下,DispatcherHandler
會將其應用於在對映處理器之前發生的例外,例如在處理器對映期間,或更早之前,例如在 WebFilter
中。
視圖解析
視圖解析允許使用 HTML 範本和模型呈現到瀏覽器,而不會將您束縛於特定的視圖技術。在 Spring WebFlux 中,視圖解析透過專用的 HandlerResultHandler 支援,後者使用 ViewResolver
實例將字串(代表邏輯視圖名稱)對映到 View
實例。然後使用 View
來呈現回應。
Web 應用程式需要使用 視圖呈現程式庫 來支援此使用案例。
處理
傳遞到 ViewResolutionResultHandler
的 HandlerResult
包含來自處理器的傳回值,以及包含在請求處理期間新增的屬性的模型。傳回值會以下列方式之一處理
-
String
、CharSequence
:要透過已組態的ViewResolver
實作列表解析為View
的邏輯視圖名稱。 -
void
:根據請求路徑(減去前導和尾隨斜線)選擇預設視圖名稱,並將其解析為View
。當未提供視圖名稱(例如,傳回模型屬性)或非同步傳回值(例如,Mono
完成時為空)時,也會發生相同的情況。 -
Rendering:用於視圖解析場景的 API。在您的 IDE 中使用程式碼完成功能探索選項。
-
Model
、Map
:要新增至請求模型的額外模型屬性。 -
任何其他:任何其他傳回值(簡單類型除外,由 BeanUtils#isSimpleProperty 判斷)都會被視為要新增至模型的模型屬性。屬性名稱是使用 慣例 從類別名稱衍生而來,除非存在處理器方法
@ModelAttribute
註解。
模型可以包含非同步、反應式類型(例如,來自 Reactor 或 RxJava)。在呈現之前,AbstractView
會將此類模型屬性解析為具體值並更新模型。單一值反應式類型會解析為單一值或無值(如果為空),而多值反應式類型(例如,Flux<T>
)會被收集並解析為 List<T>
。
組態視圖解析就像將 ViewResolutionResultHandler
Bean 新增至您的 Spring 組態一樣簡單。WebFlux 組態 為視圖解析提供專用的組態 API。
有關與 Spring WebFlux 整合的視圖技術的更多資訊,請參閱 視圖技術。
重新導向
視圖名稱中的特殊 redirect:
前綴可讓您執行重新導向。UrlBasedViewResolver
(及其子類別)將其識別為需要重新導向的指令。視圖名稱的其餘部分是重新導向 URL。
淨效果與控制器傳回 RedirectView
或 Rendering.redirectTo("abc").build()
相同,但現在控制器本身可以使用邏輯視圖名稱進行操作。諸如 redirect:/some/resource
之類的視圖名稱相對於目前的應用程式,而諸如 redirect:https://example.com/arbitrary/path
之類的視圖名稱則重新導向到絕對 URL。
與 Servlet 堆疊不同,Spring WebFlux 不支援「FORWARD」分派,因此結果不支援 forward: 前綴。 |
內容協商
ViewResolutionResultHandler
支援內容協商。它將請求媒體類型與每個選定 View
支援的媒體類型進行比較。使用第一個支援請求媒體類型的 View
。
為了支援諸如 JSON 和 XML 之類的媒體類型,Spring WebFlux 提供了 HttpMessageWriterView
,這是一個特殊的 View
,它透過 HttpMessageWriter 呈現。通常,您會透過 WebFlux 組態 將這些組態為預設視圖。如果預設視圖符合請求的媒體類型,則始終會選取並使用它們。