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} 语法非常方便。
相关推荐
桦说编程5 小时前
TransmittableThreadLocal 解读:从 CRR 机制到上下文所有权
java·后端·源码
喵个咪6 小时前
GoWind 拆解:全链 ID 类型体系——int64 定版与前端字符串化契约
前端·后端·go
喵个咪6 小时前
GoWind CMS 拆解:Flutter 设计系统内核——双态 token、四档断点与自适应壳层
前端·flutter·交互设计
xys_6786 小时前
JavaEE通关手册:初识Java
java·开发语言
文丑颜不良啊6 小时前
LeetCode2461~2480题目解析
java·leetcode
喵个咪6 小时前
GoWind CMS 拆解:发布审批——多级推进、逐级角色与全程留痕
前端·后端·go
喵个咪6 小时前
GoWind Flow 拆解:一个 Go 工作流引擎与它的双模式设计器
前端·后端·go
喵个咪6 小时前
GoWind Admin 拆解:打印模板设计器——从画布到服务端 PDF 的完整打印链路
前端·后端·go
总要学点什么7 小时前
第96篇:三维数据加载-城市建筑白模样式+着色器——让色带按体量上色,最白的那档却涂不上去
前端·gis·webgl·cesium·着色器·空间分析·白模
文丑颜不良啊7 小时前
LeetCode2441~2460题目解析
java·leetcode