AntPathMatcher、PathPatternParser :Spring中URL、Resource路径匹配神器

一、AntPathMatcher

1、AntPathMatcher简介

AntPathMatcher是 Spring 框架里用于路径匹配的工具类,主要在 URL 路由、资源定位等场景发挥作用。

Ant 风格路径匹配:
该类支持?、*、**这些通配符。
?:可匹配单个字符。
*:能匹配零个或多个任意字符。
**:可以匹配多层路径。
在这里插入图片描述

2、使用场景

URL 映射:在 Spring MVC 的 @RequestMapping 注解里,就可以使用 Ant 风格的路径。
资源定位:像 ClassPathResource 这类资源加载时,也能借助它来匹配路径。
安全控制:Spring Security 的权限配置中,同样会用到路径匹配。

真实应用场景:
客户端请求到服务器,服务器获取到请求的URL,此时可以根据URL来匹配注册到RequestMappingHandlerMapping的URL,来校验用户是否有该URL的访问权限。

3、核心方法

boolean match(String pattern, String path):用于判断路径是否与模式相匹配。
boolean matchStart(String pattern, String path):检查路径是否以指定模式开头。
String extractPathWithinPattern(String pattern, String path):从匹配的路径里提取出模式之外的部分。
Map<String, String> extractUriTemplateVariables(String pattern, String path):提取 URI 模板变量。

setPathSeparator(String pathSeparator):可以自定义路径分隔符,默认使用/setCaseSensitive(boolean caseSensitive):能够设置是否区分大小写,默认是区分的。
setTrimTokens(boolean trimTokens):可以配置是否自动去除路径中的空白符。

4、使用示例

import org.springframework.util.AntPathMatcher;

import java.util.Map;

public class AntPathMatcherExample {
    public static void main(String[] args) {
        AntPathMatcher matcher = new AntPathMatcher();
        
        // 基础匹配
        System.out.println(matcher.match("/user/*", "/user/123")); // true
        System.out.println(matcher.match("/user/*", "/user/profile")); // true
        System.out.println(matcher.match("/user/**", "/user/detail/123")); // true
        System.out.println(matcher.match("/user/{id}", "/user/123")); // true
        
        // 提取路径
        String pattern = "/static/**";
        String path = "/static/js/main.js";
        System.out.println(matcher.extractPathWithinPattern(pattern, path)); // js/main.js
        
        // 提取变量
        String uriPattern = "/user/{id}/profile";
        String uriPath = "/user/123/profile";
        Map<String, String> variables = matcher.extractUriTemplateVariables(uriPattern, uriPath);
        System.out.println(variables.get("id")); // 123
    }
}

5、线程安全性

AntPathMatcher 中的方法由于线程安全,通常建议在应用中共享同一个实例以减少开销:

// 单例模式示例
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

public boolean isMatch(String pattern, String path) {
    return PATH_MATCHER.match(pattern, path);
}

三、Spring5.0升级:PathPatternParser

1、PathPatternParser 简介

PathPatternParser 比​​AntPathMatcher有高性能路径匹配​​。
PathPatternParser 通过使用基于 NIO 的 PathPattern 实现,显著提升了路径匹配的性能,尤其在高并发和大量请求的场景下表现更为出色。

2、PathPatternParser 与 AntPathMatcher 的对比

在这里插入图片描述

3、使用

import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import org.springframework.web.util.pattern.PathMatchInfo;

public class PathVariableExtractor {
    public static void main(String[] args) {
        // 创建PathPatternParser实例
        PathPatternParser parser = new PathPatternParser();
        
        // 定义路径模式,其中包含变量
        String pattern = "/users/{userId}/orders/{orderId}";
        PathPattern pathPattern = parser.parse(pattern);
        
        // 实际请求路径
        String path = "/users/123/orders/456";
        
        // 匹配路径并提取变量
        PathMatchInfo matchInfo = pathPattern.matchAndExtract(path);
        if (matchInfo != null) {
            // 获取提取的变量值
            System.out.println("提取的变量值:");
            System.out.println("userId: " + matchInfo.getUriVariables().get("userId"));
            System.out.println("orderId: " + matchInfo.getUriVariables().get("orderId"));
        } else {
            System.out.println("路径不匹配");
        }
    }
}
// 对多个路径进行匹配并提取变量
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import org.springframework.web.util.pattern.PathMatchInfo;

import java.util.Arrays;
import java.util.List;

public class AdvancedPathVariableExtractor {
    public static void main(String[] args) {
        PathPatternParser parser = new PathPatternParser();
        String pattern = "/api/{resource}/{id}";
        PathPattern pathPattern = parser.parse(pattern);
        
        List<String> paths = Arrays.asList(
            "/api/users/1",
            "/api/products/100",
            "/api/orders/200/detail"
        );
        
        for (String path : paths) {
            PathMatchInfo matchInfo = pathPattern.matchAndExtract(path);
            if (matchInfo != null) {
                System.out.println("路径: " + path);
                System.out.println("  resource: " + matchInfo.getUriVariables().get("resource"));
                System.out.println("  id: " + matchInfo.getUriVariables().get("id"));
            } else {
                System.out.println("路径 " + path + " 不匹配");
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃了也弱了。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值