您现在的位置是:首页 >技术杂谈 >【SpringMVC源码三千问】Spring官方@RequestMapping路径匹配用法大全网站首页技术杂谈

【SpringMVC源码三千问】Spring官方@RequestMapping路径匹配用法大全

老王学源码 2024-06-24 06:01:02
简介【SpringMVC源码三千问】Spring官方@RequestMapping路径匹配用法大全

Spring 官方给出的 @RequestMapping 路径匹配的用法

@RequestMapping 的用法其实是有很多的,除了最简单的用法之外,还支持占位符、通配符、正则匹配等一些高级用法。

例如:

@RequestMapping("/resources/ima?e.png") // 匹配路径段中的一个字符
@RequestMapping("/resources/*.png") // 匹配路径段中的零个或多个字符
@RequestMapping("/resources/**") // 匹配多个路径段
@RequestMapping("/projects/{project}/versions") // 匹配路径段并将其捕获为变量
@RequestMapping("/projects/{project:[a-z]+}/versions") // 使用正则表达式匹配并捕获变量

参考:https://docs.spring.io/spring-framework/docs/5.3.9/reference/html/web.html#mvc-ann-requestmapping-uri-templates

@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 来匹配和限定 request 之外,还支持通过 RequestMethod、param、header、Content-Type 来匹配和限定 request。

所以,我们可以给接口定义相同的 url ,但是可以附加不同的限定来处理不同的 request 请求。
比如,pc端 和 mobile端 展示商品信息可以根据 header 的不同来定义不同的接口来处理,但是请求的 url 是相同的:

// 定义 pc端接口
@GetMapping(path = "/goods", headers = "myHeader=pc")

// 定义 mobile端接口
@GetMapping(path = "/goods", headers = "myHeader=mobile")

@RequestMapping 用法示例

下面来看下 @RequestMapping 的一些特殊用法

使用 @PathVariable 访问捕获的 URI 变量

@GetMapping("/owners/{ownerId}/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
    // ...
}
  • 还可以在类和方法级别声明 URI 变量,如以下示例所示:
@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {

    @GetMapping("/pets/{petId}")
    public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
        // ...
    }
}
  • 支持正则语法 {varName:regex}。例如,给定 URL “/spring-web-3.0.5.jar”,以下方法可以提取名称、版本和文件扩展名:
@GetMapping("/{name:[a-z-]+}-{version:\d\.\d\.\d}{ext:\.[a-z]+}")
public void handle(@PathVariable String name, @PathVariable String version, @PathVariable String ext) {
    // ...
}

根据 Content-Type 来限定请求映射

还可以根据 Content-Type 请求的类型缩小请求映射,如以下示例所示:

@PostMapping(path = "/pets", consumes = "application/json") // 只匹配 Content-Type="application/json"
@PostMapping(path = "/pets", consumes = "!text/plain") // 匹配除 text/plain 以外的任何内容类型

根据请求参数来限定请求映射

例如:

@GetMapping(path = "/pets/{petId}", params = "myParam") // 请求参数是否存在 myParam
@GetMapping(path = "/pets/{petId}", params = "!myParam") // 请求参数是否不存在 myParam
@GetMapping(path = "/pets/{petId}", params = "myParam=myValue") // 请求参数是否存在特定值 myParam=myValue

根据请求头 header 来限定请求映射

@GetMapping(path = "/pets", headers = "myHeader=myValue") // headers 中是否存在特定值 myHeader=myValue

小结

@RequestMapping 除了支持普通的固定 url 之外,还支持一些高级用法,比如对通配符 和 正则的支持。
还可以通过 RequestMethod、param、header、Content-Type 来限定 request。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。