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. xml
  com/ example/**/applicationContext. xml
  file:C:/ some/ path/*-context. xml
  classpath: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

  • 13
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值