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} 语法非常方便。
相关推荐
Bigger11 小时前
告别版本焦虑:如何为 Hugo 项目定制专属构建环境
前端·架构·go
皮皮林55112 小时前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
代码匠心13 小时前
AI 自动编程:一句话设计高颜值博客
前端·ai·ai编程·claude
_AaronWong14 小时前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode14 小时前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户54330814419414 小时前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo14 小时前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭15 小时前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木15 小时前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮15 小时前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github