W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Micronaut HTTP 服務(wù)器支持以與傳統(tǒng) Java 應(yīng)用程序中的 Servlet 過濾器類似(但反應(yīng)性)的方式將過濾器應(yīng)用于請求/響應(yīng)處理。
過濾器支持以下用例:
裝飾傳入的HttpRequest
傳出 HttpResponse 的修改
實施橫切關(guān)注點(diǎn),例如安全性、跟蹤等。
對于服務(wù)端應(yīng)用,可以實現(xiàn)HttpServerFilter接口的doFilter方法。
doFilter 方法接受 HttpRequest 和 ServerFilterChain 的實例。
ServerFilterChain 接口包含已解析的過濾器鏈,其中鏈中的最終條目是匹配的路由。 ServerFilterChain.proceed(io.micronaut.http.HttpRequest) 方法恢復(fù)請求的處理。
proceed(..) 方法返回一個 Reactive Streams Publisher,它發(fā)出要返回給客戶端的響應(yīng)。過濾器的實現(xiàn)者可以訂閱發(fā)布者并改變發(fā)出的 MutableHttpResponse 以在將響應(yīng)返回給客戶端之前修改響應(yīng)。
為了將這些概念付諸實踐,讓我們看一個例子。
過濾器在事件循環(huán)中執(zhí)行,因此必須將阻塞操作卸載到另一個線程池。
編寫過濾器
假設(shè)您希望使用某個外部系統(tǒng)將每個請求跟蹤到 Micronaut“Hello World”示例。該系統(tǒng)可以是數(shù)據(jù)庫或分布式跟蹤服務(wù),并且可能需要 I/O 操作。
你不應(yīng)該在你的過濾器中阻塞底層的 Netty 事件循環(huán);相反,過濾器應(yīng)該在任何 I/O 完成后繼續(xù)執(zhí)行。
例如,考慮使用 Project Reactor 組合 I/O 操作的 TraceService:
使用 Reactive Streams 的 TraceService 示例
Java | Groovy | Kotlin |
|
|
|
Mono 類型創(chuàng)建執(zhí)行潛在阻塞操作的邏輯,以從請求中寫入跟蹤數(shù)據(jù)
由于這只是一個示例,因此該邏輯尚未執(zhí)行任何操作
Schedulers.boundedElastic 執(zhí)行邏輯
然后,您可以將此實現(xiàn)注入到您的過濾器定義中:
HttpServerFilter 示例
Java | Groovy | Kotlin |
|
|
|
Filter 注釋定義過濾器匹配的 URI 模式
該類實現(xiàn)了 HttpServerFilter 接口
之前定義的 TraceService 是通過構(gòu)造函數(shù)注入的
最后一步是編寫 HttpServerFilter 接口的 doFilter 實現(xiàn)。
doFilter 實現(xiàn)
Java | Groovy | Kotlin |
|
|
|
調(diào)用 TraceService 來跟蹤請求
如果調(diào)用成功,過濾器將使用 Project Reactor 的 switchMap 方法恢復(fù)請求處理,該方法調(diào)用 ServerFilterChain 的 proceed 方法
最后,Project Reactor 的 doOnNext 方法將 X-Trace-Enabled 標(biāo)頭添加到響應(yīng)中。
前面的示例演示了一些關(guān)鍵概念,例如在處理請求和修改傳出響應(yīng)之前以非阻塞方式執(zhí)行邏輯。
這些示例使用 Project Reactor,但是您可以使用任何支持反應(yīng)流規(guī)范的反應(yīng)框架
Filter可以通過設(shè)置patternStyle使用不同風(fēng)格的pattern進(jìn)行路徑匹配。默認(rèn)情況下,它使用 AntPathMatcher 進(jìn)行路徑匹配。使用 Ant 時,映射使用以下規(guī)則匹配 URL:
?匹配一個字符
* 匹配零個或多個字符
** 匹配路徑中的零個或多個子目錄
路徑 | 示例匹配路徑 |
---|---|
|
任何路徑 |
|
customer/joy, customer/jay |
|
customer/adam/id, com/amy/id |
|
customer/adam, customer/adam/id, customer/adam/name |
|
customer/index.html, customer/adam/profile.html, customer/adam/job/description.html |
另一個選項是基于正則表達(dá)式的匹配。要使用正則表達(dá)式,請設(shè)置 patternStyle = FilterPatternStyle.REGEX。 pattern 屬性應(yīng)包含一個正則表達(dá)式,該正則表達(dá)式應(yīng)與提供的 URL 完全匹配(使用 Matcher#matches)。
首選使用 FilterPatternStyle.ANT,因為模式匹配比使用正則表達(dá)式更高效。當(dāng)您的模式無法使用 Ant 正確編寫時,應(yīng)使用 FilterPatternStyle.REGEX。
錯誤狀態(tài)
從 chain.proceed 返回的發(fā)布者永遠(yuǎn)不應(yīng)該發(fā)出錯誤。在上游過濾器發(fā)出錯誤或路由本身拋出異常的情況下,應(yīng)該發(fā)出錯誤響應(yīng)而不是異常。在某些情況下,可能需要知道錯誤響應(yīng)的原因,為此目的,如果響應(yīng)是由于發(fā)出或拋出異常而創(chuàng)建的,則響應(yīng)中存在一個屬性。原始原因存儲為屬性 EXCEPTION。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: