最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中的路徑匹配器AntPathMatcher詳解

 更新時(shí)間:2023年09月25日 10:01:58   作者:騎個(gè)小蝸牛  
這篇文章主要介紹了Spring中的路徑匹配器AntPathMatcher詳解,Spring的PathMatcher路徑匹配器接口,用于支持帶通配符的資源路徑匹配,本文提供了部分實(shí)現(xiàn)代碼,需要的朋友可以參考下

PathMatcher接口

Spring的PathMatcher路徑匹配器接口,用于支持帶通配符的資源路徑匹配。

使用場(chǎng)景

PathMatcher接口在Spring的許多場(chǎng)景下使用,比如:

  • PathMatchingResourcePatternResolver:資源掃描,啟動(dòng)時(shí)掃描并加載資源
  • AbstractUrlHandlerMapping:請(qǐng)求路徑映射到 Controller
  • WebContentInterceptor:攔截器攔截路徑分析

接口方法

方法描述
boolean isPattern(String path)判斷路徑是否是模式
boolean match(String pattern, String path)判斷路徑是否完全匹配
boolean matchStart(String pattern, String path)判斷路徑是否前綴匹配
前綴匹配的意思:路徑能與模式的前面部分匹配,但模式可能還有后面多余部分
例如:/test能前綴匹配/test/{id}(但模式還有多余的/{id}部分未匹配)
String extractPathWithinPattern(String pattern, String path)得到模式匹配的部分值
該方法只返回路徑的實(shí)際模式匹配部分
例如:myroot/*.html 匹配 myroot/myfile.html 路徑,結(jié)果為 myfile.html
Map<String, String> extractUriTemplateVariables(String pattern, String path)提取路徑中的路徑參數(shù)值
Comparator<String> getPatternComparator(String path)得到一個(gè)排序比較器,用于對(duì)匹配到的所有路徑進(jìn)行排序
String combine(String pattern1, String pattern2)合并兩個(gè)模式

AntPathMatcher類

AntPathMatcher是Spring為PathMatcher接口提供的默認(rèn)實(shí)現(xiàn),支持Ant風(fēng)格的路徑匹配。

匹配規(guī)則

AntPathMatcher支持的匹配規(guī)則:

規(guī)則描述
?匹配一個(gè)字符
*在一個(gè)路徑段中匹配零個(gè)、一個(gè)或多個(gè)字符
**匹配零個(gè)或多個(gè)路徑段,直到路徑結(jié)束
{id}匹配一個(gè)路徑段,并將該路徑段的值作為變量id的變量值
{id:[a-z]+}匹配一個(gè)滿足正則([a-z]+)路徑段,并將該路徑段的值作為變量id的變量值

舉例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        // ?
        System.out.println(matcher.match("/test/a?c", "/test/abc"));// true
        // *
        System.out.println(matcher.match("/test/*", "/test/"));// true
        System.out.println(matcher.match("/test/*", "/test/aa"));// true
        System.out.println(matcher.match("/test/*.html", "/test/aa"));// false
        // **
        System.out.println(matcher.match("/test/**", "/test/"));// true
        System.out.println(matcher.match("/test/**", "/test/aa"));// true
        System.out.println(matcher.match("/test/**", "/test/aa/bb"));// true
        // {id}
        System.out.println(matcher.match("/test/{id}", "/test/111"));// true
        System.out.println(matcher.match("/test/a{id}", "/test/a111"));// true
        System.out.println(matcher.match("/test/{id}/aa", "/test/111/aa"));// true
        System.out.println(matcher.match("/test/{id}-{name}/aa", "/test/111-haha/aa"));// true
        // {id:[a-z]+}
        System.out.println(matcher.match("/test/{id:[a-z]+}", "/test/111"));// false
        System.out.println(matcher.match("/test/{id:[a-z]+}", "/test/abc"));// true
        System.out.println(matcher.match("/test/{id:\\w+}", "/test/1a_"));// true
        System.out.println(matcher.match("/test/{id:\\w+}", "/test/--"));// false
    }

一些不匹配情況原因:

模式路徑原因
/user/aaa//user/aaa結(jié)束符不一致
/user/*//user/aaa結(jié)束符不一致

實(shí)際在Spring項(xiàng)目中使用的時(shí)候,你會(huì)發(fā)現(xiàn):就算實(shí)際請(qǐng)求的結(jié)束符為 / ,但還是能匹配成功。這又是為什么呢?

兩個(gè)關(guān)鍵屬性:

  • useSuffixPatternMatch:設(shè)置是否使用后綴模式匹配,如“/user”是否匹配/user.*,默認(rèn)是這種模式下,實(shí)際請(qǐng)求.后面加任何后綴,都會(huì)匹配到。如:實(shí)際請(qǐng)求“/user.html”能匹配上“/user”。
  • useTrailingSlashMatch:設(shè)置是否使用后綴路徑模式匹配,如“/user”是否匹配“/user/”,默認(rèn)是這種模式下,實(shí)際請(qǐng)求加、后綴,都會(huì)匹配到。如:實(shí)際請(qǐng)求“/user/”能匹配上“/user”。

關(guān)鍵源碼:

PatternsRequestCondition類的getMatchingPattern方法

private String getMatchingPattern(String pattern, String lookupPath) {
		// 模式與路徑相等,直接返回模式
		if (pattern.equals(lookupPath)) {
			return pattern;
		}
		// 如果使用后綴模式匹配,返回的模式會(huì)拼接上合適的后綴,如.html
		if (this.useSuffixPatternMatch) {
			if (!this.fileExtensions.isEmpty() && lookupPath.indexOf('.') != -1) {
				for (String extension : this.fileExtensions) {
					if (this.pathMatcher.match(pattern + extension, lookupPath)) {
						return pattern + extension;
					}
				}
			}
			else {
				boolean hasSuffix = pattern.indexOf('.') != -1;
				if (!hasSuffix && this.pathMatcher.match(pattern + ".*", lookupPath)) {
					return pattern + ".*";
				}
			}
		}
		if (this.pathMatcher.match(pattern, lookupPath)) {
			return pattern;
		}
		// 如果使用后綴路徑模式匹配,返回的模式會(huì)拼接上/
		if (this.useTrailingSlashMatch) {
			if (!pattern.endsWith("/") && this.pathMatcher.match(pattern + "/", lookupPath)) {
				return pattern + "/";
			}
		}
		return null;
	}

因此,getMatchingPattern方法返回的模式再與請(qǐng)求路徑進(jìn)行模式匹配當(dāng)然能匹配上了。

主要方法

1. isPattern

判斷路徑是否是模式。

只要路徑中擁有 * 、 ? 、 {} ,則就是模式。

public boolean isPattern(@Nullable String path) {
    if (path == null) {
        return false;
    }
    boolean uriVar = false;
    for (int i = 0; i < path.length(); i++) {
        char c = path.charAt(i);
        if (c == '*' || c == '?') {
            return true;
        }
        if (c == '{') {
            uriVar = true;
            continue;
        }
        if (c == '}' && uriVar) {
            return true;
        }
    }
    return false;
}

示例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        System.out.println(matcher.isPattern("/test/{id}"));// true
    }

2. match

判斷路徑是否完全匹配

public boolean match(String pattern, String path) {
    return doMatch(pattern, path, true, null);
}

示例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        System.out.println(matcher.match("/test/*", "/test/111"));// true
        System.out.println(matcher.match("/test/**", "/test/111/222"));// true
        System.out.println(matcher.match("/test/{id}", "/test/111"));// true
        System.out.println(matcher.match("/test/{id}/aa", "/test/111/aa"));// true
        System.out.println(matcher.match("/test/{id}-{name}/aa", "/test/111-haha/aa"));// true
        System.out.println(matcher.match("/test/{id}-{name}/aa", "/test/111-/aa"));// true
    }

3. matchStart

判斷路徑是否前綴匹配

前綴匹配的意思:路徑能與模式的前面部分匹配,但模式可能還有后面多余部分(可以理解為模式是否是以路徑開頭)

public boolean matchStart(String pattern, String path) {
    return doMatch(pattern, path, false, null);
}

示例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        System.out.println(matcher.matchStart("/test/*", "/test"));// true
        System.out.println(matcher.matchStart("/test/aa/*", "/test"));// true
        System.out.println(matcher.matchStart("/test/{id}", "/test"));// true
        System.out.println(matcher.matchStart("/test/{id}-{name}/aa", "/test"));// true
        System.out.println(matcher.matchStart("/test/{id}", "/test/111/222"));// false
    }

4. extractPathWithinPattern

得到模式匹配的映射部分。找出通過*或者?匹配上的那一段路徑及其后續(xù)路徑。

示例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        System.out.println(matcher.extractPathWithinPattern("/test/*", "/test"));//
        System.out.println(matcher.extractPathWithinPattern("/test/*", "/test/aa"));// aa
        System.out.println(matcher.extractPathWithinPattern("/test/**", "/test/aa/bb"));// aa/bb
        System.out.println(matcher.extractPathWithinPattern("/test/a?c/aa", "/test/abc/aa"));// abc/aa
        System.out.println(matcher.extractPathWithinPattern("/test/aa?c/aa/cc", "/test/abc/aa"));// abc/aa
    }

5. extractUriTemplateVariables

路徑必須完全匹配(否則拋出異常),并提取路徑中的路徑參數(shù)值。

示例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        System.out.println(matcher.extractPathWithinPattern("/test/*", "/test"));//
        System.out.println(matcher.extractPathWithinPattern("/test/*", "/test/aa"));// aa
        System.out.println(matcher.extractPathWithinPattern("/test/**", "/test/aa/bb"));// aa/bb
        System.out.println(matcher.extractPathWithinPattern("/test/a?c/aa", "/test/abc/aa"));// abc/aa
        System.out.println(matcher.extractPathWithinPattern("/test/aa?c/aa/cc", "/test/abc/aa"));// abc/aa
    }

6. getPatternComparator

得到一個(gè)排序比較器。

public Comparator<String> getPatternComparator(String path) {
		return new AntPatternComparator(path);
	}

7. combine

合并兩個(gè)模式。 示例:

    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        System.out.println(matcher.combine("/test/*", "/test/aa"));// /test/aa
        System.out.println(matcher.combine("/test/*", "/test/aa/bb"));// /test/test/aa/bb
        System.out.println(matcher.combine("/test/**", "/test/aa"));// /test/aa
        System.out.println(matcher.combine("/test/{id}", "/test/aa"));// /test/{id}/test/aa
    }

到此這篇關(guān)于Spring中的路徑匹配器AntPathMatcher詳解的文章就介紹到這了,更多相關(guān)AntPathMatcher詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java微信公眾平臺(tái)開發(fā)(7) 公眾平臺(tái)測(cè)試帳號(hào)的申請(qǐng)

    Java微信公眾平臺(tái)開發(fā)(7) 公眾平臺(tái)測(cè)試帳號(hào)的申請(qǐng)

    這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開發(fā)第七步,微信公眾平臺(tái)測(cè)試帳號(hào)的申請(qǐng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java時(shí)區(qū)轉(zhuǎn)換及Date類實(shí)現(xiàn)原理解析

    Java時(shí)區(qū)轉(zhuǎn)換及Date類實(shí)現(xiàn)原理解析

    這篇文章主要介紹了Java時(shí)區(qū)轉(zhuǎn)換及Date類實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java序列化機(jī)制詳解

    Java序列化機(jī)制詳解

    Java 序列化機(jī)制是一種將對(duì)象轉(zhuǎn)換為字節(jié)流的過程,以便在網(wǎng)絡(luò)上傳輸或保存到文件中,并能在需要時(shí)將字節(jié)流還原為對(duì)象,這一機(jī)制通過實(shí)現(xiàn) java.io.Serializable 接口來實(shí)現(xiàn),同時(shí)涉及到一些關(guān)鍵概念和注意事項(xiàng),需要的朋友可以參考下
    2023-12-12
  • Springboot+netty實(shí)現(xiàn)Web聊天室

    Springboot+netty實(shí)現(xiàn)Web聊天室

    這篇文章主要介紹了利用springboot+netty實(shí)現(xiàn)一個(gè)簡(jiǎn)單Web聊天室,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-12-12
  • Java LinkedList集合功能實(shí)例解析

    Java LinkedList集合功能實(shí)例解析

    這篇文章主要介紹了Java LinkedList集合功能實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot基于knife4j生成接口文檔方式

    SpringBoot基于knife4j生成接口文檔方式

    Knife4j介紹一個(gè)基于Swagger的JavaAPI文檔生成工具,提供美觀界面和高級(jí)功能,本文詳細(xì)介紹了在SpringBoot項(xiàng)目中集成Knife4j的方法,包括導(dǎo)入依賴、創(chuàng)建Swagger配置和WebMvcConfiguration配置類等
    2026-05-05
  • Java中Date時(shí)區(qū)的轉(zhuǎn)換代碼示例

    Java中Date時(shí)區(qū)的轉(zhuǎn)換代碼示例

    這篇文章主要給大家介紹了關(guān)于Java中Date時(shí)區(qū)轉(zhuǎn)換的相關(guān)資料,當(dāng)在不同的時(shí)區(qū)使用相同程序,時(shí)間的值只會(huì)為當(dāng)?shù)貢r(shí)間,這樣就會(huì)造成時(shí)間混亂,需要的朋友可以參考下
    2023-07-07
  • java項(xiàng)目中classpath的理解

    java項(xiàng)目中classpath的理解

    這篇文章介紹了java項(xiàng)目中classpath的理解,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • MyBatis-Plus通過version機(jī)制實(shí)現(xiàn)樂觀鎖的思路

    MyBatis-Plus通過version機(jī)制實(shí)現(xiàn)樂觀鎖的思路

    version機(jī)制的核心思想就是,假設(shè)發(fā)生并發(fā)沖突的幾率很低,只有當(dāng)更新數(shù)據(jù)的時(shí)候采取檢查是否有沖突,而判斷是否有沖突的依據(jù)就是version的值是否被改變了,這篇文章主要介紹了MyBatis-Plus通過version機(jī)制實(shí)現(xiàn)樂觀鎖的思路,需要的朋友可以參考下
    2021-09-09
  • 關(guān)于Logback+MyBatis日志輸出問題的一些思考

    關(guān)于Logback+MyBatis日志輸出問題的一些思考

    這篇文章主要介紹了關(guān)于Logback+MyBatis日志輸出問題的一些思考,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,
    2023-09-09

最新評(píng)論

土默特左旗| 嵊州市| 贡嘎县| 三亚市| 宁南县| 叶城县| 克山县| 原平市| 乌鲁木齐县| 建瓯市| 朝阳县| 陵川县| 昌吉市| 三原县| 江安县| 新余市| 静海县| 奇台县| 邻水| 邵东县| 海盐县| 博湖县| 横山县| 绥阳县| 富锦市| 承德县| 射洪县| 手游| 通江县| 原平市| 高陵县| 灵丘县| 武鸣县| 富川| 商河县| 丽水市| 绿春县| 陇南市| 信宜市| 弥渡县| 彰化县|