如何使用Spring @RequestMapping路径表达式匹配字符串并捕获参数?
当然可以实现!复用Spring @RequestMapping的路径匹配逻辑
你完全可以复用Spring内部@RequestMapping同款的路径匹配机制,不管是做URL匹配还是捕获路径变量,Spring都提供了现成的工具类,不用自己从零实现正则或者匹配逻辑。下面是具体的实现方案:
核心工具类选择
Spring提供了两种主流的路径匹配实现,和@RequestMapping的逻辑完全一致:
- PathPatternMatcher:Spring 5.3+推荐使用的新实现,性能更优,支持更多高级匹配特性(比如正则约束的路径变量、更精准的通配符控制)
- AntPathMatcher:传统的实现,兼容性好,适合旧版本Spring项目
实现步骤(以Spring Security过滤器为例)
1. 初始化匹配器
你可以直接创建实例,或者在Spring容器中注入(Spring已经默认注册了这两个匹配器的Bean):
// 推荐:使用PathPatternMatcher private final PathPatternMatcher pathMatcher = new PathPatternMatcher(); // 兼容旧版本:使用AntPathMatcher // private final AntPathMatcher antPathMatcher = new AntPathMatcher();
2. 在过滤器中进行匹配并捕获变量
在自定义过滤器的doFilter方法中,组合上下文路径和路径信息,然后执行匹配:
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // 组合上下文路径与路径信息,得到完整的请求路径 String fullRequestPath = httpRequest.getContextPath() + (httpRequest.getPathInfo() != null ? httpRequest.getPathInfo() : ""); // 定义要匹配的路径模式(和@RequestMapping里的写法完全一致) String targetPattern = "/api/foo/bar/{id}"; // --- 方式1:使用PathPatternMatcher --- PathPattern pattern = pathMatcher.parse(targetPattern); PathContainer requestPathContainer = PathContainer.parsePath(fullRequestPath); if (pattern.matches(requestPathContainer)) { // 匹配成功,获取捕获的路径变量 PathMatchInfo matchInfo = pattern.match(requestPathContainer); String capturedId = matchInfo.getUriVariables().get("id"); System.out.println("路径匹配成功,捕获的id值:" + capturedId); // 输出:1 // 这里可以添加你的业务逻辑,比如权限校验等 } // --- 方式2:使用AntPathMatcher --- /* if (antPathMatcher.match(targetPattern, fullRequestPath)) { // 提取路径变量 Map<String, String> variables = antPathMatcher.extractUriTemplateVariables(targetPattern, fullRequestPath); String capturedId = variables.get("id"); System.out.println("路径匹配成功,捕获的id值:" + capturedId); // 业务逻辑... } */ // 继续执行过滤器链 chain.doFilter(request, response); }
匹配规则说明
两种匹配器都遵循@RequestMapping的路径规则,比如:
{variable}:匹配单段路径,捕获为变量{variable:[a-z]+}:带正则约束的变量,只匹配符合正则的路径段*:匹配单级路径的任意字符**:匹配多级路径的任意字符
这样你就完全复用了Spring MVC的路径匹配逻辑,和控制器里的@RequestMapping行为完全一致。
内容的提问来源于stack exchange,提问作者Justin Albano
相关产品推荐
相关产品推荐

