@RequestMapping
是 SpringMVC 中最常用的定义请求映射关系的注解。
下面我们来分析一下它的源码。
@RequestMapping
先看下 @RequestMapping
的定义:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
/*************限制匹配范围的参数******************/
// 请求方法限定
RequestMethod[] method() default {};
// 请求参数限定
String[] params() default {};
// 请求头限定
String[] headers() default {};
// 接收的 Content-Type 内容类型限定
String[] consumes() default {};
// 返回的 Content-Type 内容类型限定
String[] produces() default {};
}
可以看到,@RequestMapping
除了可以定义 path 之外,还可以通过 RequestMethod、param、header、Content-Type 来更加精细化的匹配 request。
所以,在 SpringMVC 中抽象出了 RequestMappingInfo
来支持多样化的 request 请求映射。
RequestMappingInfo
RequestMappingInfo 是用来保存 @RequestMapping
中定义的请求映射信息的。
它里面包含了一系列的请求映射条件:
1、PathPatternsRequestCondition、PatternsRequestCondition
2、RequestMethodsRequestCondition -- 处理 RequestMethod,如:GET, POST, PUT, DELETE 等
3、ParamsRequestCondition -- 处理 params
4、HeadersRequestCondition -- 处理 headers
5、ConsumesRequestCondition -- 处理 consumes Content-Type
6、ProducesRequestCondition -- 处理 produces Content-Type
7、RequestCondition (用户自定义的 RequestCondition)
RequestCondition
RequestCondition 是 request 请求映射条件,RequestCondition 可以组合叠加使用。
RequestCondition 的类图如下:
PathPatternsRequestCondition: 处理简单 path 和通配符的请求映射
PathPatternsRequestCondition
是一种逻辑析取请求条件,用于根据一组 URL 路径模式匹配 request 请求。
它内部是通过解析出的 PathPattern
来匹配字符串。
- PathPattern
用于解析 URL 路径,处理简单的字符串 path 和含通配符的。
PathPattern 使用以下规则匹配 URL 路径:
- ?: 匹配一个字符
- *: 匹配路径段中的零个或多个字符
- **: 匹配零个或多个路径段,直到路径结束
- {spring}: 匹配路径段并将其捕获为名为 “spring” 的变量
- {spring:[a-z]+}: 匹配正则
[a-z]+
,并将匹配值赋值给 “spring” 的路径变量 - {*spring}: 匹配零个或多个路径段,直到路径结束,并将其捕获为名为 “spring” 的变量
注意:
PathPattern 与 AntPathMatcher 不同,** 仅在模式末尾受支持。例如/pages/{**}
有效,但/pages/{**}/details
无效。
这同样适用于捕获变体 {*spring}。目的是在比较模式的特异性时消除歧义。
用法示例:
/pages/t?st.html - 匹配/pages/test.html以及/pages/tXst.html,但不匹配/pages/trast.html
/resources/*.png - 匹配 resources 目录中的所有 .png 文件
/resources/** - 匹配 /resources/ 路径下的所有文件,包括/resources/image.png和/resources/css/spring.css
/resources/{*path} - 匹配/resources/和/resources下的所有文件,并在名为“path”的变量中捕获它们的相对路径/resources/image.png将与“path”匹配→ “/image.png”和/resources/css/spring.css将与“path”匹配→ “/css/spring.css”
/resources/{filename:\\w+}.dat - 可以匹配 /resources/spring.dat,并将值 “spring” 赋值给 filename 变量
参考:
org.springframework.web.util.pattern.PathPattern
的源码注释
PatternsRequestCondition: 处理 ant 风格的请求映射
PatternsRequestCondition
是一种逻辑析取请求条件,用于根据一组URL路径模式匹配 request 请求。
它内部是通过 AntPathMatcher
来匹配字符串的。
- AntPathMatcher
AntPathMatcher
是 Ant 样式路径模式的 PathMatcher 实现,代码的一部分实现是从 ApacheAnt 借来的。
映射使用以下规则匹配URL:
- ?: 匹配一个字符
- *: 匹配零个或多个字符
- **: 匹配路径中的零个或多个目录
- {spring:[a-z]+}: 匹配正则
[a-z]+
,并将匹配值赋值给 “spring” 的路径变量
示例
com/t?st.jsp - 匹配 com/test.jsp,但也匹配 com/tast.jsp 或 com/txst.jsp
com/*.jsp - 匹配 com 目录中的所有 .jsp 文件
com/**/test.jsp - 匹配 com 路径下的所有 test.jsp 文件
org/springframework/**/*.jsp - 匹配 org/springframework 路径下的所有 .jsp 文件
org/**/servlet/bla.jsp - 匹配 org/springframework/servlet/bla.jsp,但也匹配 org/springframework/testing/servlet/bla.jsp 和 org/servlet/bla.jsp
com/{filename:\\w+}.jsp - 将与 com/test.jsp 匹配,并将值 test 赋值给 filename 变量
参考:
org.springframework.util.AntPathMatcher
源码注释