Spring框架中PathMatchingResourcePatternResolver解析资源路径并匹配资源模式
PathMatchingResourcePatternResolver是Spring框架中用于解析资源路径并匹配资源模式的一个工具类。它常用于在Spring的上下文中加载资源,如:配置文件、类路径下的文件加载等。
PathMatchingResourcePatternResolver是一个Ant模式通配符的Resource查找器,可以用来查找类路径下或者文件系统中的资源获取文件系统文件。
PathMatchingResourcePatternResolver位于spring-core包之中。
一、classpath*:前缀文件读取
- 加载classpath下mapper对应的xml\
public static void main(String[] args) throws IOException {List<String> list = List.of("classpath*:mapper/mysql/*.xml", "classpath:mapper/oracle/*.xml","classpath:*.properties");List<Resource> resources = getResources(list);System.out.println(resources.size());}public static List<Resource> getResources(List<String> list) throws IOException {PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();List<Resource> resources = new ArrayList<>();for (String path : list) {resources.addAll(List.of(resolver.getResources(path)));}return resources;}
上述案例可以读取到classpath下指定路径的所有xml和properties文件。
二、Ant-style样式通配符
当路径包含Ant-style样式通配符,解析器遵循一个更复杂单已定义的过程来尝试解析通配符,如下:
/ WEB-INF/*-context. xmlcom/ example/**/applicationContext. xmlfile:C:/ some/ path/*-context. xmlclasspath:com/ example/**/applicationContext. xml
示例:
public static void main(String[] args) throws IOException {List<String> list = List.of("META-INF/**/*.lua", "META-INF/spring/**/*.xml");List<Resource> resources = getResources(list);System.out.println(resources.size());}public static List<Resource> getResources(List<String> list) throws IOException {PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();List<Resource> resources = new ArrayList<>();for (String path : list) {resources.addAll(List.of(resolver.getResources(path)));}return resources;}
三、基于AntPathMatcher的路径匹配
- Ant风格通配符
?:匹配单个字符
*:匹配0或多个字符
**:匹配0或多个目录
- 首先创建AntPathMatcher对象
PathMatcher pathMatcher = new AntPathMatcher();
- 是否是一个Ant模式字符串,即:是否包含通配符字符串
Assertions.assertFalse(matcher.isPattern("/api/redis"));Assertions.assertFalse(matcher.isPattern("ap/redis/t-a"));Assertions.assertTrue(matcher.isPattern("ap/redis/*"));Assertions.assertTrue(matcher.isPattern("ap/redis/**/a/b"));Assertions.assertTrue(matcher.isPattern("ap/redis/a*"));Assertions.assertTrue(matcher.isPattern("ap/redis/a?"));Assertions.assertTrue(matcher.isPattern("ap/redis/{name}"));
- url是否匹配指定的Ant模式
Assertions.assertTrue(matcher.match("api/**/test","api/a/b/test"));Assertions.assertTrue(matcher.match("api/a*b/test","api/aAbcb/test"));Assertions.assertFalse(matcher.match("api/a*b/test","api/aAbcB/test"));Assertions.assertTrue(matcher.match("api/a?b/test","api/acb/test"));Assertions.assertFalse(matcher.match("api/a?b/test","api/acdb/test"));Assertions.assertTrue(matcher.match("api/{name}/test","api/acdb/test"));Assertions.assertFalse(matcher.match("api/a/**/b","api/a/bc"));
- url是否匹配Ant模式,且以指定的模式开头
Assertions.assertTrue(matcher.matchStart("api/{name}/test","api/acdb/test"));Assertions.assertTrue(matcher.matchStart("api/a/*","api/a/test"));Assertions.assertTrue(matcher.matchStart("api/a/*","api/a/bc"));Assertions.assertTrue(matcher.matchStart("api/a/**/b","api/a/bc"));Assertions.assertTrue(matcher.matchStart("api/a/**/b","api/a/bc/dd"));Assertions.assertTrue(matcher.matchStart("api/a/*/b","api/a/bc/b"));Assertions.assertFalse(matcher.matchStart("api/a/*/b","api/a/bc/d"));Assertions.assertTrue(matcher.matchStart("api/a/c*","api/a/cbc"));Assertions.assertFalse(matcher.matchStart("api/a/c*","a/api/a/cbc"));Assertions.assertFalse(matcher.matchStart("api/a/c*","api/a/c/dd"));
- 提取Ant通配符匹配开始之后的路由,支持‘*’、‘**’、‘?’
Assertions.assertEquals(matcher.extractPathWithinPattern("/docs/cvs/commit.html","/docs/cvs/commit.html"),"");Assertions.assertEquals(matcher.extractPathWithinPattern("/docs/*","/docs/cvs/commit"),"cvs/commit");Assertions.assertEquals(matcher.extractPathWithinPattern("/docs/cvs/*.html","/docs/cvs/commit.html"),"commit.html");Assertions.assertEquals(matcher.extractPathWithinPattern("/docs/**","/docs/cvs/commit"),"cvs/commit");Assertions.assertEquals(matcher.extractPathWithinPattern("/docs/**\\/*.html","/docs/cvs/commit.html"),"cvs/commit.html");Assertions.assertEquals(matcher.extractPathWithinPattern("/*.html","/docs/cvs/commit.html"),"docs/cvs/commit.html");Assertions.assertEquals(matcher.extractPathWithinPattern("*.html","/docs/cvs/commit.html"),"/docs/cvs/commit.html");Assertions.assertEquals(matcher.extractPathWithinPattern("*","/docs/cvs/commit.html"),"/docs/cvs/commit.html");Assertions.assertEquals(matcher.extractPathWithinPattern("/a/b?","/a/bc/d"),"bc/d");
- 提取Ant风格url中变量
Map<String,String> uriTemplate = matcher.extractUriTemplateVariables("api/{userid}/{id}","api/1002356/11");Assertions.assertEquals(uriTemplate.get("userid"),"1002356");Assertions.assertEquals(uriTemplate.get("id"),"11");
- 将两个URL拼接成一个新的url
Assertions.assertEquals(matcher.combine(null, null),"");Assertions.assertEquals(matcher.combine("/hotels", null),"/hotels");Assertions.assertEquals(matcher.combine(null, "/hotels"),"/hotels");Assertions.assertEquals(matcher.combine("/hotels", "/bookings"),"/hotels/bookings");Assertions.assertEquals(matcher.combine("/hotels", "bookings"),"/hotels/bookings");Assertions.assertEquals(matcher.combine("/hotels/*", "bookings"),"/hotels/bookings");Assertions.assertEquals(matcher.combine("/hotels/**", "/bookings"),"/hotels/**/bookings");Assertions.assertEquals(matcher.combine("/hotels", "{hotel}"),"/hotels/{hotel}");Assertions.assertEquals(matcher.combine("/hotels/*", "{hotel}"),"/hotels/{hotel}");Assertions.assertEquals(matcher.combine("/hotels/**", "{hotel}"),"/hotels/**/{hotel}");Assertions.assertEquals(matcher.combine("/*.html", "/hotels.html"),"/hotels.html");Assertions.assertEquals(matcher.combine("/*.html", "/hotels"),"/hotels.html");Assertions.assertThrows(IllegalArgumentException.class,()->matcher.combine("/*.html", "/*.txt"));
- 给定一个url返回一个可以按照显式顺序排序的Comparator对象
Comparator<String> comparator1 = matcher.getPatternComparator("/hotels/new");Comparator<String> comparator2 = matcher.getPatternComparator("/hotels/{hotel}");Comparator<String> comparator3 = matcher.getPatternComparator("/hotels/*");
开源SDK:https://github.com/mingyang66/spring-parent