为什么 Servlet Filter 匹配所有路径的 url-pattern 是 "
/*"不能是 "/**",而 Spring 的 interceptor 匹配所有路径的 url-pattern却是 "/**"?
目录
1. Servlet 规范里 url-pattern 的定义与语法
2. 为什么 Servlet 不允许 /**
3. Spring MVC 的路径匹配设计
4. 调用链
5. 对比总结表
6. 架构设计建议
1. Servlet 规范里的 url-pattern 定义
Servlet 规范(Jakarta EE / Java EE)是“容器级”标准。
所有的 url-pattern(包括 Servlet 和 Filter 的)都必须符合这个规范,严格定义了四种模式:
a. 精确匹配
/foo/bar
b. 路径前缀匹配
/foo/*
c. 扩展名匹配(后缀)
*.jsp
d. 根路径匹配
/
👑 规范里的要求非常严格:
只能是上述四种形式。不能写任意通配符,比如
/**
Servlet 3.0 规范( Section 12.2 Specification of Mappings)
The string patterns are matched according to the following rules:
A string beginning with a ‘/’ and ending with a ‘/*’ is used for path mapping.
A string beginning with a ‘*.’ indicates an extension mapping.
The special string "/" represents the default servlet.
All other strings are used for exact matches only.
最新servlet6.0中也基本保持一致:详见 Jakarta Servlet 6.0 规范,Section 12.2
2. 为什么 Servlet 不允许 /**?
因为规范里明确没有定义这种模式。
Servlet 规范要保证的是:
-
容器可以高效、确定性地匹配
-
只需要简单字符串前缀/后缀比较
-
没有递归或复杂的路径分段逻辑
/** 会引入什么问题?
-
是多层路径任意深度的匹配(模糊)
-
没法用简单的字符串前缀切割来判断
-
规范避免了这种复杂性和潜在歧义
3. Spring MVC 的路径匹配设计
Spring MVC 的路径匹配是在 Servlet 规范之上自己扩展的机制。
Spring 是这样设计的:
Spring 的所有 Controller 调用,都走 DispatcherServlet
DispatcherServlet 里有 HandlerMapping
HandlerMapping 的职责就是做「路径映射」
Spring 在 HandlerMapping 里实现了自己的路径模式系统
Spring 的路径模式是基于Ant-style 路径模式 ,源码通过 AntPathMatcher 或 PathPatternParser实现:
-
/*:一层路径 -
/**:多层路径 -
/foo/**/bar:中间可有多层 -
/foo/*/bar:中间固定一层 -
*.do:后缀匹配 -
甚至支持路径变量
/foo/{id}
➜ 在 Spring 里:
-
/**代表任意深度、任意路径 -
用于极其灵活的路由映射
Spring 的设计目标是:
-
方便 Controller 的路由
-
更符合 RESTful 风格
-
支持更复杂的 API 模式
4. Servlet Filter 和 Spring Interceptor 的调用链位置
理解调用链是最关键的架构点。
图示:
+---------------------------------------------------------------+
| HTTP Request |
+---------------------------------------------------------------+
|
v
+----------------------------+
| Servlet Filter | (/*, *.jsp etc.)
+----------------------------+
|
v
+----------------------------+
| DispatcherServlet |
+----------------------------+
|
v
+----------------------------+
| Spring HandlerInterceptor | (/**, /api/** etc.)
+----------------------------+
|
v
+----------------------------+
| Controller Method |
+----------------------------+
5. 对比总结
| 特性 | Servlet Filter | Spring MVC Interceptor |
|---|---|---|
| 定义层级 | Java EE / Jakarta EE 规范(容器层) | Spring MVC 框架层 |
| 配置位置 | web.xml / @WebFilter | Java Config / XML / 注解 |
| 匹配模式 | 严格限定:/, /*, /foo/*, *.jsp | Ant-style:/**, /api/** 等 |
| 匹配机制 | 由 Servlet 容器实现 | 由 Spring DispatcherServlet 实现 |
| 可拦截范围 | 所有请求,包括静态资源 | 仅 Controller 的请求 |
| 主要用途 | 认证、日志、跨域、全局安全控制 | 业务层鉴权、参数注入、审计等 |
6. 架构设计建议
不要用 Filter 做业务逻辑
把业务逻辑分离到 Interceptor / AOP
文档链接
-
Servlet 规范(Jakarta Servlet 6.0)
👉 PDF - Section 12.2 -
Spring 官方文档 - MVC HandlerInterceptor
👉 Spring Framework Reference

被折叠的 条评论
为什么被折叠?



