SpringBoot中web请求路径匹配的两种风格

在 Spring Boot (特别是 Spring MVC) 中,当一个请求(例如 /user/1)到达时,框架需要决定由哪个 Controller 的哪个方法来处理。这个过程就叫做路径匹配

Spring Boot 2.6.0 开始,路径匹配策略发生了重大变化。目前主要支持以下两种风格:

  1. AntPathMatcher (经典/传统风格)
  2. PathPatternParser (现代/高性能风格)

下面详细介绍这两种风格的区别、语法以及如何配置。


1. AntPathMatcher (经典风格)

这是 Spring 早期一直使用的默认匹配器,基于 Apache Ant 的文件路径匹配规则。它的特点是非常灵活,但在处理复杂 URL 时性能稍弱。

核心语法
  • ?:匹配 1 个 字符。
    • /user/get? -> 匹配 /user/get1, /user/getA
  • *:匹配 0 个或多个 字符(仅限当前层级目录)。
    • /user/* -> 匹配 /user/1, /user/abc
    • 不匹配 /user/1/details (跨层级了)
  • **:匹配 0 个或多个 目录(支持多层级)。
    • /user/** -> 匹配 /user/1, /user/1/details/edit
特点
  • 灵活性极高** 可以放在路径的中间
    • 例如:/api/**/details 可以匹配 /api/user/details/api/order/v1/details
  • 性能:基于字符串操作,每次匹配都需要重新计算,对于高并发下的长 URL,性能略逊于新版。
  • 现状:在 Spring Boot 2.6 之前是默认值。

2. PathPatternParser (现代风格)

这是 Spring 5.3 引入,并成为 Spring Boot 2.6+ 的默认配置。它是专门为 Web URL 设计的,而不是照搬文件路径规则。

核心语法

基本兼容 AntPathMatcher,但在通配符位置上有严格限制:

  • ?*:用法同上。
  • **只能放在路径的末尾
    • 合法/user/**
    • 非法/user/**/details (启动时会直接报错!)
  • {*pathVariable}:支持更强大的路径变量捕获(这是新特性)。
    • /resources/{*path} -> 可以匹配 /resources/img/icon.png,并且把 img/icon.png 整个捕获给变量 path
特点
  • 高性能 :它在应用启动时就把 URL 解析成了一棵语法树 (AST),匹配请求时是基于树节点的匹配,而不是字符串正则,速度非常快。
  • 更严格 :禁止在路径中间使用 **,这消除了很多歧义匹配的问题。
  • 现状Spring Boot 2.6 及以后版本的默认值。

3. 两种风格对比

特性 AntPathMatcher PathPatternParser
引入时间 Spring 很早就有了 Spring 5.3+
Spring Boot 默认 < 2.6 版本 ≥ 2.6 版本
** 的位置 可以放在中间 (如 /a/**/b) 只能放在末尾
匹配算法 字符串操作/正则 预解析语法树 (AST)
性能 一般 极高
路径变量 支持 {id} 支持 {id}{*path} (捕获剩余路径)
兼容性问题 兼容性极好(老项目多用它) 某些老旧库(如老版 Swagger/Springfox)可能不支持

4. 如何配置切换?

如果你升级了 Spring Boot 到 2.6+,发现以前写的 /api/**/xxx 接口报错了,或者集成的 Swagger 文档挂了,你可以通过修改 application.yml 来切换回老模式。

配置属性: spring.mvc.pathmatch.matching-strategy

使用 PathPatternParser (默认,推荐)
yaml 复制代码
spring:
  mvc:
    pathmatch:
      matching-strategy: path_pattern_parser
回退到 AntPathMatcher (老模式)
yaml 复制代码
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

5. 总结

  1. 新项目 :强烈建议使用默认的 PathPatternParser。它的性能更好,且"禁止中间双星号"的限制其实有助于保持 API 设计的整洁。
  2. 老项目迁移 :如果你的老代码里大量使用了 /a/**/b 这种中间通配符,或者使用了不兼容 PathPatternParser 的第三方库(如旧版 Springfox Swagger),为了快速迁移,可以将策略改回 ant_path_matcher
  3. 捕获剩余路径 :如果你需要实现类似"网关"的功能,把某个前缀后的所有路径都截取下来,PathPatternParser 的 /{*path} 语法非常方便。
相关推荐
渡我白衣1 小时前
并行的野心与现实——彻底拆解 C++ 标准并行算法(<execution>)的模型、陷阱与性能真相
java·开发语言·网络·c++·人工智能·windows·vscode
tecwlcvi3231 小时前
安卓版谷歌地图,Google地图高清版,谷歌地球,谷歌翻译,谷歌(Chrome)浏览器,手机版Edge,浏览器等安卓版浏览器下载
前端·chrome·edge
bill4471 小时前
BPMN2.0,flowable工作流指向多节点,并且只能选择其中一个节点的处理方式
java·工作流引擎·bpmn
Q_Q5110082851 小时前
python+django/flask医药垃圾分类管理系统
spring boot·python·django·flask·node.js·php
2022.11.7始学前端1 小时前
n8n第四节 表单触发器:让问卷提交自动触发企微消息推送
java·前端·数据库·n8n
m0_740043731 小时前
Axios 请求示例 res.data.data
前端·javascript·vue.js
程序员小寒1 小时前
超详细的 EventLoop 解读及模拟实现
前端·javascript
Catcharlotte1 小时前
异常(3)
java
冴羽1 小时前
太好看了!3 个动漫变真人 Nano Banana Pro 提示词
前端·人工智能·aigc