当前位置: 首页 > 科技观察

你用过SpringMVC接口定义过RequestMapping的细节吗?

时间:2023-03-14 19:36:54 科技观察

环境:Spring5.3.25概述您可以使用@RequestMapping注解将请求映射到控制器方法。它具有多种属性,可以根据URL、HTTP方法、请求参数、标头和媒体类型进行匹配。您可以在类级别使用它来表达共享映射,或者在方法级别使用它来缩小到特定端点映射。还有HTTP方法特定的快捷方式变体@RequestMapping:@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping@PatchMapping提供的快捷方式是自定义注解,因为大多数控制器方法应该映射到特定的HTTP方法而不是使用@RequestMapping,默认情况下,匹配所有HTTP方法。在类级别,仍然需要@RequestMapping来表示共享映射和统一前缀。以下示例具有类型级和方法级映射:@RestController@RequestMapping("/persons")classPersonController{@GetMapping("/{id}")publicPersongetPerson(@PathVariableLongid){//...}@PostMapping@ResponseStatus(HttpStatus.CREATED)publicvoidadd(@RequestBodyPersonperson){//...}}URIpattern@RequestMapping方法可以使用URLpattern进行映射。有两个选项:PathPattern-与URL路径匹配的预解析模式,并且也被预解析为PathContainer。该解决方案专为Web使用而设计,可高效处理编码和路径参数,并高效匹配。AntPathMatcherPathPattern是web应用的推荐方案,也是SpringWebFlux的唯一选择。在5.3版本之前,AntPathMatcher是SpringMVC中的唯一选项,并且一直是默认的。但是,可以在MVC配置中启用PathPattern。PathPattern支持与AntPathMatcher相同的模式语法。此外,它还支持捕获模式,例如{*spring},用于匹配路径末尾的0个或多个路径段。PathPattern还限制使用**来匹配多个路径段,这样它只允许出现在模式的末尾。在为给定请求选择最佳匹配模式时,这消除了很多歧义。有关完整的模式语法,请参阅PathPattern和AntPathMatcher。一些示例模式:"/resources/ima?e.png"-匹配路径段中的一个字符"/resources/*.png"-匹配路径段中的零个或多个字符"/resources/**"-匹配多个pathsegments"/projects/{project}/versions"-匹配pathsegments并将其捕获为变量"/projects/{project:[a-z]+}/versions"-匹配regex并捕获变量getURI变量即可访问通过@PathVariable。例如:@GetMapping("/owners/{ownerId}/pets/{petId}")publicPetfindPet(@PathVariableLongownerId,@PathVariableLongpetId){//...}您可以在类和方法中声明URIlevel变量,如下例所示:@Controller//classlevel应该很少使用@RequestMapping("/owners/{ownerId}")publicclassOwnerController{@GetMapping("/pets/{petId}")publicPetfindPet(@PathVariableLongownerId,@PathVariableLongpetId){//...}}URI变量将自动转换为适当的类型,否则将抛出TypeMismatchException。默认支持简单类型(int、long、Date等),您也可以注册对任何其他数据类型的支持。请参见类型转换和DataBinder。您可以显式命名URI变量(例如,@PathVariable("customId")),但如果名称相同,并且您的代码在Java8上使用调试信息或-parameters(在标记方法上使用参数名称是recorded)thecompilerflagscompilation,这个细节可以省略。后缀匹配从5.3开始,SpringMVC不再默认执行.*后缀模式匹配,其中映射到/person的控制器也隐式映射到/person.*。因此,路径扩展不再用于解释请求的响应内容类型——例如/person.pdf、/person.xml等。当浏览器习惯于发送难以一致解释的Accept标头时,以这种方式使用文件扩展名是必要的。目前,这不再是必需的,应该首选使用Accept标头。随着时间的推移,文件扩展名的使用在很多方面都被证明是有问题的。当它与URI变量、路径参数和URI编码的使用重叠时,可能会导致歧义。关于基于URL的授权和安全性的推理。要在5.3之前的版本中完全禁用路径扩展,请设置以下内容:useSuffixPatternMatching(false),请参阅PathMatchConfigurerfavorpatheextension(false),请参阅ContentNegotiationConfigurer通过“接受”以外的方式请求内容类型仍然有用header,例如浏览时在浏览器中输入URL时。路径扩展的一种安全替代方法是使用查询参数策略。如果必须使用文件扩展名,请考虑通过ContentNegotiationConfigurer的mediaTypes属性将它们限制为明确注册的扩展名列表。Consumermediatype可以根据请求的content-type缩小请求映射,如下://使用consumes属性按内容类型缩小映射范围@PostMapping(path="/pets",consumes="application/json")publicvoidaddPet(@RequestBodyPetpet){//...}consume属性还支持否定表达式-例如,!text/plain用于除text/plain之外的任何内容类型。您可以在类级别声明共享消费属性。但是,与大多数其他请求映射属性不同,当在类级别使用时,方法级别使用属性覆盖,而不是扩展类级别声明。MediaType为常用的媒体类型提供常量,例如APPLICATION_JSON_VALUE和APPLICATION_XML_VALUE。Producermediatype您可以根据Accept请求头和控制器方法生成的内容类型列表来缩小请求映射,如下例所示://使用produces属性按内容类型缩小映射.@GetMapping(path="/pets/{petId}",produces="application/json")@ResponseBodypublicPetgetPet(@PathVariableStringpetId){//...}媒体类型可以指定字符集。支持非表达式-例如,!text/plain表示除“text/plain”之外的任何内容类型。您可以在类级别声明一个共享的produces属性。然而,与大多数其他请求映射属性不同,当在类级别使用时,方法级别会产生属性覆盖,而不是扩展类级别声明。Requestparameters和Header可以根据请求参数条件缩小请求映射。您可以测试是否存在请求参数(myParam)或特定值(myParam=myValue)。以下示例显示如何测试特定值://测试myParam是否等于myValue@GetMapping(path="/pets/{petId}",params="myParam=myValue")publicvoidfindPet(@PathVariableStringpetId){//...}你也可以使用相同的请求头条件,如下例所示://测试myHeader是否等于myValue@GetMapping(path="/pets",headers="myHeader=myValue")publicvoidfindPet(@PathVariableStringpetId){//...}HTTP请求方法@GetMapping(和@RequestMapping(method=HttpMethod.GET))透明地支持请求映射的HTTPHEAD。控制器方法不需要改变。应用于javax.servlet.http中的响应包装器。HttpServlet,确保Content-Length标头设置为写入的字节数(实际上没有写入响应)。@GetMapping(和@RequestMapping(method=HttpMethod.GET))隐式映射到并支持HTTPHEAD。HTTPHEAD请求的处理方式与HTTPGET类似,只是它不是写入文本,而是计算字节数并设置Content-Length标头。默认情况下,HTTPOPTIONS是通过将Allow响应标头设置为所有具有匹配URL模式的@RequestMapping方法中列出的HTTP方法列表来处理的。对于没有HTTP方法声明的@RequestMapping,允许标头设置为GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS。控制器方法应始终声明受支持的HTTP方法(例如,通过使用特定于HTTP方法的变量:@GetMapping、@PostMapping等)。您可以显式地将@RequestMapping方法映射到HTTPHEAD和HTTPOPTIONS,但这在一般情况下是不必要的。自定义注解SpringMVC支持使用复合注解进行请求映射。这些注释本身使用@RequestMapping进行元注释,并组合重新声明@RequestMapping属性的一个子集(或全部),具有更窄、更具体的目的。@GetMapping、@PostMapping、@PutMapping、@DeleteMapping和@PatchMapping是复合注释的示例。提供它们的原因是大多数控制器方法应该映射到特定的HTTP方法,而不是使用默认匹配所有HTTP方法的@RequestMapping。如果您想要一个组合注释的示例,请查看它们是如何声明的。SpringMVC还支持使用自定义请求匹配逻辑的自定义请求映射属性。这是一个更高级的选项,需要继承RequestMappingHandlerMapping并覆盖getCustomMethodCondition方法,您可以在其中检查自定义属性并返回您自己的RequestCondition。显示注册允许您以编程方式注册处理程序方法,可用于动态注册或高级情况,例如不同url下的同一处理程序的不同实例。下面的例子注册了一个处理器方法:)。建造();//指定接口处理的方法Methodmethod=UserHandler.class.getMethod("getUser",Long.class);mapping.registerMapping(信息,处理程序,方法);}}完成的!!!