Spring源碼解析 - AntPathMatcher

来源:http://www.cnblogs.com/leftthen/archive/2016/02/24/5212221.html
-Advertisement-
Play Games

ant匹配規則;PathMatcher介面;通過測試用例看AntPathMatcher的使用


最近在看SpringMVC的源碼,發現request分發時,路徑匹配最後是委托給AntPathMatcher實現的.索性看看吧.

文章摘要:

  1. ant匹配規則

  2. PathMatcher介面

  3. 通過測試用例看AntPathMatcher的使用

 

ant匹配規則

AntPathMatcher如名使用的ant 的匹配規則,我們先看看吧.

  字元wildcard    描述

   ?         匹配一個字元

   *         匹配0個及以上字元

   **         匹配0個及以上目錄directories

看幾個官方的例子吧:

  com/t?st.jsp -             匹配: com/test.jsp  ,  com/tast.jsp  ,  com/txst.jsp
  com/*.jsp -             匹配: com文件夾下的全部.jsp文件
  com/**/test.jsp -          匹配: com文件夾和子文件夾下的全部.jsp文件,
  org/springframework/**/*.jsp -    匹配: org/springframework文件夾和子文件夾下的全部.jsp文件
  org/**/servlet/bla.jsp -       匹配: org/springframework/servlet/bla.jsp  ,  org/springframework/testing/servlet/bla.jsp  ,  org/servlet/bla.jsp

 

PathMatcher介面

主要是判斷是否匹配pattern,並解析出path中的參數

 1 package org.springframework.util;
 2 
 3 public interface PathMatcher {
 4 
 5     /**
 6      * 判斷傳入的path是否可以作為pattern使用
 7      */
 8     boolean isPattern(String path);
 9 
10     /**
11      * 使用pattern匹配path
12      */
13     boolean match(String pattern, String path);
14 
15     /**
16      * 如名,是否開始部分匹配
17      */
18     boolean matchStart(String pattern, String path);
19 
20     /**
21      * 提取path中匹配到的部分,如pattern(myroot/*.html),path(myroot/myfile.html),返回myfile.html
22      */
23     String extractPathWithinPattern(String pattern, String path);
24 
25     /**
26      * 提取path中匹配到的部分,只是這邊還需跟占位符配對為map,
27      * 如pattern(/hotels/{hotel}),path(/hotels/1),解析出"hotel"->"1"
28      */
29     Map<String, String> extractUriTemplateVariables(String pattern, String path);
30 
31     /**
32      * 提供比較器
33      */
34     Comparator<String> getPatternComparator(String path);
35 
36     /**
37      * 合併pattern,pattern1然後pattern2
38      */
39     String combine(String pattern1, String pattern2);
40 
41 }

 

 

通過測試用例看AntPathMatcher的使用

一看測試用例,瞬間服了,人家開發真是規範.

人家整這麼規範,還是有空直接看源碼好了.這邊挑幾個簡單的例子看看就好

1. match 跟 matchStart 的差異,這個我們在測試用例看下麵的情況會比較明確

  這邊的代碼,我截取了一小部分

 1 package org.springframework.util;
 2 public class AntPathMatcherTests {
 3     @Test
 4     public void match() {
 5         // ...
 6         assertFalse(pathMatcher.match("/x/x/**/bla", "/x/x/x/"));
 7         // ...
 8     }
 9     @Test
10     public void withMatchStart() {
11         // ...
12         assertTrue(pathMatcher.matchStart("/x/x/**/bla", "/x/x/x/"));
13         // ...
14     }
15 }

 

2. extractPathWithinPattern,代碼很清楚,不廢話

 1 package org.springframework.util;
 2 public class AntPathMatcherTests {
 3     @Test
 4     public void extractPathWithinPattern() throws Exception {
 5         // ...
 6         assertEquals("", pathMatcher.extractPathWithinPattern("/docs/commit.html", "/docs/commit.html"));
 7         assertEquals("cvs/commit", pathMatcher.extractPathWithinPattern("/docs/*", "/docs/cvs/commit"));
 8         assertEquals("docs/cvs/commit", pathMatcher.extractPathWithinPattern("/d?cs/*", "/docs/cvs/commit"));
 9         // ...
10     }
11 }

3. extractUriTemplateVariables

 1 package org.springframework.util;
 2 public class AntPathMatcherTests {
 3     @Test
 4     public void extractUriTemplateVariables() throws Exception {
 5         Map<String, String> result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1");
 6         assertEquals(Collections.singletonMap("hotel", "1"), result);
 7         // ...
 8         result = pathMatcher.extractUriTemplateVariables("/{page}.*", "/42.html");
 9         assertEquals(Collections.singletonMap("page", "42"), result);
10         // ...
11     }
12     /**
13      * SPR-7787
14      */
15     @Test
16     public void extractUriTemplateVarsRegexQualifiers() {
17         Map<String, String> result = pathMatcher.extractUriTemplateVariables(
18                 "{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar",
19                 "com.example-sources-1.0.0.jar");
20         assertEquals("com.example", result.get("symbolicName"));
21         assertEquals("1.0.0", result.get("version"));
22         // ...
23     }
24 }

4. combine

 1 package org.springframework.util;
 2 public class AntPathMatcherTests {
 3     @Test
 4     public void combine() {
 5         // ...
 6         assertEquals("/hotels", pathMatcher.combine("/hotels", null));
 7         assertEquals("/hotels/booking", pathMatcher.combine("/hotels/*", "/booking"));
 8         assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "booking"));
 9         assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "/booking"));
10         assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "/booking"));
11         assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels/*", "{hotel}"));
12         assertEquals("/hotels/**/{hotel}", pathMatcher.combine("/hotels/**", "{hotel}"));
13         assertEquals("/hotels/*/booking/{booking}", pathMatcher.combine("/hotels/*/booking", "{booking}"));
14     }
15 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本人文筆不好,大致說說自己的困惑 隨著2016的到來,一年一度的職業規劃即將而來,因為本人一直從事著C#工作,也接觸了一些前端知識。 但是由於微軟老大哥,技術更新太快,學習成本太高,但是眾所周知C#工資並不高,畢竟人活著要吃一口飯, ,因此產生換個技術的想法。 但是換什麼技術啊?真是糾結啊 比如手機
  • 安裝JDK 選擇安裝目錄 安裝過程中會出現兩次 安裝提示 。第一次是安裝 jdk ,第二次是安裝 jre 。建議兩個都安裝在同一個java文件夾中的不同文件夾中。(不能都安裝在java文件夾的根目錄下,jdk和jre安裝在同一文件夾會出錯) 如下圖所示 1:安裝jdk 隨意選擇目錄 只需把預設安裝目...
  • 半形全形的處理是字元串處理的常見問題,本文嘗試為大家提供一個思路。 一、概念 全形字元unicode編碼從65281~65374 (十六進位 0xFF01 ~ 0xFF5E)半形字元unicode編碼從33~126 (十六進位 0x21~ 0x7E)空格比較特殊,全形為 12288(0x3000),
  • 指針: 一、聲明 一個 int 類型的 指針 然後 賦值。 二、聲明中直接賦值。 三、空指針 四、懸空指針 野指針: 懸空指針本質上就是 聲明瞭一個 指針類型的變數【如:int *p】,並且沒有賦值。在沒有賦初值的情況下,利用這個指針進行修改【如:*p=100】。就相當於這個指針指向了一個未知的地址
  • 之前在[譯]更快的方式實現PHP數組去重討論了使用array_flip後再調用array_keys函數替換直接調用array_unique函數實現數組去重性能較好。由於原文沒有給出源碼分析和測試的結果,導致給讀者造成迷惑,在此說聲抱歉。為瞭解開讀者的疑惑,筆者承諾了會補上源碼的分析,現在此補上詳細的...
  • 原文:https://nikic.github.io/2012/03/28/Understanding-PHPs-internal-array-implementation.html 歡迎來到”給PHP開發者的PHP源碼”系列的第四部分,這一部分我們會談論PHP數組在內部是如何表示和在代碼庫里使用...
  • 在PHP的核心代碼中,變數被稱為ZVAL。這個結構之所以那麼重要是有原因的,不僅僅是因為PHP使用弱類型而C使用強類型。那麼ZVAL是怎麼解決這個問題的呢?要回答這個問題,我們需要認真的查看ZVAL類型的定義。要查看這個定義,讓我們嘗試在lxr頁面的定義搜索框里搜索zval。乍一眼看去,我們似乎找不...
  • /** * 計算百分比. * @param dividend 被除數 * @param divisor 除數 * @return 結果 */ private String getPercent(long dividend, long divisor) { NumberFormat format =
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...