搶佔先機
VMware 提供培訓和認證,助您加速前進。
瞭解更多最近釋出的 Spring Framework 5.3 M1 公告 提到“Spring MVC 帶有 PathPattern
解析,用於高效的 URL 匹配”。本文將對此進行更深入的介紹。
在 Spring 應用程式中,AntPathMatcher
用於識別 Spring 配置中的 classpath、檔案系統、遠端資源以及其他資源。它也曾用於 Spring MVC 中匹配 URL 路徑。隨著時間的推移,Web 應用程式中模式(patterns)的使用在數量和語法上不斷增長,AntPathMatcher
也在不斷發展以滿足這些需求,但一些痛點問題仍然沒有得到解決。
在 Web 應用程式中,每個請求都需要多次進行模式匹配,因此效能和效率方面的任何提升都至關重要。然而,String
模式匹配限制了能實現的效果。
在匹配請求的多個模式中選擇最具體的模式多年來一直具有挑戰性,並且沒有簡單的方法可以在不影響其他情況的前提下使其更具可預測性。
將 String
路徑與 String
模式進行匹配使得難以避免 URI 編碼問題。例如,是應該先解碼傳入路徑然後再匹配嗎?這樣做允許模式本身在宣告時不需要包含編碼字元,但如果請求路徑包含 %2F
或 %3B
(分別代表 /
和 ;
)怎麼辦?一旦解碼,它們就會改變路徑的結構,從而使其更難可靠地匹配。我們可以透過 UrlPathHelper#urlDecode
保留編碼的請求路徑,但那樣我們就無法使用字首 Servlet 對映,因為 servletPath 本身是被解碼的,而且我們的模式也需要編碼。
路徑引數帶來了類似的挑戰。它們可以在匹配之前被移除,但如果我們想透過 @MatrixVariable
提取它們怎麼辦?我們可以透過 UrlPathHelper#removeSemicolonContent
將它們留在路徑中,但這樣模式就必須考慮路徑引數了。
在 Spring Framework 5.0 中引入 Spring WebFlux 是重新思考所有這些問題並建立替代方案的好機會。這導致瞭解析後的 PathPattern
的建立,用於與表示 URL 路徑的解析後的 PathContainer
進行匹配。
模式(Patterns)在啟動時被解析,並在執行時重複使用以進行高效的 URL 匹配。效率提高了多少?很難在沒有具體用例的情況下給出確切數字,但我們的 jmh 基準測試 顯示吞吐量提高了 6-8 倍,分配率降低了 30-40%。您可以根據您的應用程式調整基準測試以獲得更準確的數字。
PathPattern
與 AntPathMatcher
語法相容,但以下情況除外:
支援額外的語法來匹配並捕獲末尾的 0 個或多個路徑段,例如 "/foo/{*spring}"
。這在 REST API 中非常有用,可以作為包羅永珍的模式,並透過 @PathVariable
訪問捕獲的路徑段。
對 "**"
多段匹配的支援僅允許在模式的末尾。這有助於消除在為給定請求選擇最接近匹配時的大多數歧義原因。
PathContainer
有助於解決剩餘的問題。例如,它從不解碼整個路徑,而是將其分解並單獨解碼路徑段,同時也會移除路徑引數,然後逐個匹配解碼和規範化後的結果值。因此,編碼後的 "/"
和 ";"
無法改變路徑的結構,並且路徑引數仍然可用。這意味著無需配置如何解析請求路徑,也無需權衡取捨。
從 Spring Framework 5.3 開始,Spring MVC 支援使用 PathPattern
,所有 HandlerMapping
實現都暴露了一個屬性,可以將 PathPatternParser
設定為 AntPathMatcher
的替代方案。啟用此功能的最簡單方法是在 MVC 配置的路徑匹配選項中配置 PathPatternParser
。
反過來,如果 DispatcherServlet
檢測到任何啟用瞭解析模式的 HandlerMapping
,它將在執行時解析 URL 路徑,並將其儲存在眾所周知的請求屬性下。也可以提前使用 ServletRequestPathFilter
來完成相同的操作,在這種情況下,DispatcherServlet
將不會再次解析它。
在某些情況下,一個 HandlerMapping
可能啟用瞭解析模式,而另一個使用 AntPathMatcher
。例如,第三方庫可以註冊自己的 HandlerMapping
bean,但未啟用解析模式。雖然每個 HandlerMapping
獨立進行自己的匹配,但攔截器等其他元件需要能夠支援和使用解析後的 RequestPath
(配合 PathPattern
)或 String lookupPath
(配合 AntPathMatcher
),具體取決於哪個可用。
因此,從 5.3 版本開始,此類元件使用 ServletRequestPathUtils
來檢查哪個可用,並相應地使用 PathPattern
或 AntPathMatcher
。大多數情況下,應用程式無需擔心這一點,而且模式語法大體相同,因此應該能正常工作。
此外,在 5.3 版本中,Spring MVC 中透過路徑擴充套件進行內容協商的字尾模式匹配以及其他選項已預設關閉。多年來,這已被證明在許多方面存在問題。因此,當使用 PathPatternParser
時,甚至都不支援此功能。即使在 5.3 中使用 AntPathMatcher
,如果您想繼續使用這些選項,也需要重新啟用它們。
總之,展望未來,我們希望 Spring MVC 應用程式能夠切換到使用 PathPattern
而不是 AntPathMatcher
,以利用其效率提升、改進的語法以及更可預測地處理 URL 路徑問題的方式。請在您的應用程式中嘗試使用 M1 版本,可以進行基準測試,並向我們提供任何反饋。