【SpringMVC源码三千问】@RequstMapping和RequestCondition

@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 的类图如下:
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 源码注释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老王学源码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值