环境:Spring5.3.25
概述
你可以使用@RequestMapping注释将请求映射到控制器(controller)方法。它有各种属性,可以根据URL、HTTP方法、请求参数、头和媒体类型进行匹配。你可以在类级别使用它来表示共享映射,或者在方法级别使用它来缩小到特定的端点映射。
还有HTTP方法特定的快捷方式变体@RequestMapping:
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
提供的快捷方式是自定义注释,因为大多数控制器方法应该映射到特定的HTTP方法,而不是使用@RequestMapping,默认情况下,匹配所有HTTP方法。在类级别上仍然需要@RequestMapping来表示共享映射,统一前缀。
下面的例子有类型级和方法级的映射:
URI模式
@RequestMapping方法可以使用URL模式进行映射。有两种选择:
PathPattern - 一个与URL路径匹配的预解析模式,也被预解析为PathContainer。设计为web使用,该解决方案有效地处理编码和路径参数,并有效地匹配。
AntPathMatcher
PathPattern是web应用程序的推荐解决方案,也是Spring WebFlux中的唯一选择。在5.3版本之前,AntPathMatcher是Spring MVC中的唯一选择,并且一直是默认选项。然而,PathPattern可以在MVC配置中启用。
PathPattern支持与AntPathMatcher相同的模式语法。此外,它还支持捕获模式,例如{*spring},用于在路径的末尾匹配0个或多个路径段。PathPattern还限制使用**来匹配多个路径段,这样它只允许在模式的末尾使用。在为给定的请求选择最佳匹配模式时,这消除了许多不明确的情况。完整的模式语法请参考PathPattern和AntPathMatcher。
一些示例模式:
"/resources/ima?e.png" -匹配路径段中的一个字符
"/resources/*.png" -在路径段中匹配零个或多个字符
"/resources/**" -匹配多个路径段
"/projects/{project}/versions" -匹配路径段并将其作为变量捕获
"/projects/{project:[a-z]+}/versions" -用正则表达式匹配并捕获变量
获取的URI变量可以通过@PathVariable访问。例如:
你可以在类和方法级别声明URI变量,如下例所示:
URI变量会自动转换为适当的类型,或者引发TypeMismatchException异常。默认情况下支持简单类型(int、long、Date等),你也可以注册对任何其他数据类型的支持。请参阅类型转换和DataBinder。
你可以显式地命名URI变量(例如,@PathVariable("customId")),但是如果名称相同,并且你的代码是用调试信息或Java 8上的-parameters(用了该标记方法上的参数名称就被记录下来)编译器标记编译的,则可以省略该细节。
后缀匹配
从5.3开始,默认情况下Spring MVC不再执行.*后缀模式匹配,其中映射到/person的控制器也隐式映射到/person.*。因此,路径扩展不再用于解释响应所请求的内容类型——例如/person.pdf、/person.xml等等。
当浏览器用来发送难以一致解释的Accept头时,以这种方式使用文件扩展名是必要的。目前,这不再是必要的,使用Accept报头应该是首选。
随着时间的推移,文件扩展名的使用在许多方面都被证明是有问题的。当它与URI变量、路径参数和URI编码的使用重叠时,可能会导致歧义。关于基于url的授权和安全性的推理。
要在5.3之前的版本中完全禁用路径扩展的使用,请设置如下:
useSuffixPatternMatching(false),参见PathMatchConfigurer
favorpatheextension(false),参见ContentNegotiationConfigurer
通过“Accept”头以外的方式请求内容类型仍然是有用的,例如在浏览器中输入URL时。路径扩展的安全替代方法是使用查询参数策略。如果必须使用文件扩展名,请考虑通过ContentNegotiationConfigurer的mediaTypes属性将它们限制为显式注册的扩展名列表。
Consumer媒体类型
你可以根据请求的Content-Type缩小请求映射,示例如下:
consume属性还支持否定表达式——例如,!text/plain表示除text/plain以外的任何内容类型。
你可以在类级别声明共享消费属性。然而,与大多数其他请求映射属性不同的是,当在类级使用时,方法级使用属性重写,而不是扩展类级声明。
MediaType为常用的媒体类型提供常量,例如APPLICATION_JSON_VALUE和APPLICATION_XML_VALUE。
Producer媒体类型
你可以根据Accept请求头和控制器方法产生的内容类型列表来缩小请求映射,如下面的例子所示:
媒体类型可以指定字符集。支持非表达式——例如,!text/plain表示除“text/plain”之外的任何内容类型。
你可以在类级别声明一个共享的produces属性。然而,与大多数其他请求映射属性不同的是,当在类级使用时,方法级产生属性重写,而不是扩展类级声明。
请求参数与Header
可以根据请求参数条件缩小请求映射。你可以测试是否有请求参数(myParam),或者是否有特定的值(myParam=myValue)。下面的例子展示了如何测试一个特定的值:
你也可以使用相同的请求头条件,如下面的例子所示:
HTTP请求Method
@GetMapping(和@RequestMapping(method=HttpMethod.GET))对请求映射透明地支持HTTP HEAD。控制器方法不需要改变。应用于javax.servlet.http中的响应包装器。HttpServlet,确保Content-Length头被设置为写入的字节数(而不实际写入响应)。
@GetMapping(和@RequestMapping(method=HttpMethod.GET))隐式映射到并支持HTTP HEAD。处理HTTP HEAD请求时就像处理HTTP GET一样,不同的是,它不是写入正文,而是计算字节数,并设置Content-Length报头。
默认情况下,HTTP OPTIONS是通过将Allow响应头设置为所有具有匹配URL模式的@RequestMapping方法中列出的HTTP方法列表来处理的。
对于没有HTTP方法声明的@RequestMapping,允许头被设置为GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS。控制器方法应该始终声明支持的HTTP方法(例如,通过使用特定于HTTP方法的变量:@GetMapping、@PostMapping和其他)。
你可以显式地将@RequestMapping方法映射到HTTP HEAD和HTTP OPTIONS,但在一般情况下这是不必要的。
自定义注解
Spring MVC支持对请求映射使用组合注释。这些注释本身是用@RequestMapping进行元注释的,并且组合起来重新声明@RequestMapping属性的一个子集(或全部),目的更窄、更具体。
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping和@PatchMapping是组合注释的例子。提供它们的原因是,大多数控制器方法都应该映射到特定的HTTP方法,而不是使用@RequestMapping,默认情况下,它匹配所有HTTP方法。如果需要一个组合注释的示例,请查看它们是如何声明的。
Spring MVC还支持使用自定义请求匹配逻辑的自定义请求映射属性。这是一个更高级的选项,需要子类化RequestMappingHandlerMapping并覆盖getCustomMethodCondition方法,在该方法中你可以检查自定义属性并返回自己的RequestCondition。
显示的注册
你可以以编程方式注册处理程序方法,可以将其用于动态注册或高级情况,例如不同url下相同处理程序的不同实例。下面的例子注册了一个处理器方法:
完毕!!!