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} 语法非常方便。
相关推荐
侠客行03178 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪9 小时前
深入浅出LangChain4J
java·langchain·llm
子兮曰9 小时前
OpenClaw入门:从零开始搭建你的私有化AI助手
前端·架构·github
吴仰晖9 小时前
使用github copliot chat的源码学习之Chromium Compositor
前端
1024小神9 小时前
github发布pages的几种状态记录
前端
老毛肚10 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎11 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
不像程序员的程序媛11 小时前
Nginx日志切分
服务器·前端·nginx
Yvonne爱编码11 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚11 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言