Spring MVC 中@RequestMapping 注解是如何工作的?

@RequestMapping 是 Spring MVC 中最核心、最常用的注解之一,它负责将 HTTP 请求映射到 Controller 中的处理方法(Handler Method)。

1. @RequestMapping 的作用:

  • 映射请求: 将 HTTP 请求的 URL、请求方法(GET、POST 等)、请求头、请求参数等信息,与 Controller 中的方法进行映射。
  • 处理请求: 当 Spring MVC 接收到一个 HTTP 请求时,它会根据 @RequestMapping 的配置,找到对应的 Controller 方法来处理请求。

2. @RequestMapping 的属性:

@RequestMapping 注解有多个属性,可以灵活地配置请求映射规则:

  • value / path (最常用)指定请求的 URL 路径。可以是一个字符串,也可以是一个字符串数组(匹配多个路径)。支持 Ant 风格的路径匹配(?***)。
    • ?:匹配一个字符
    • *: 匹配零个或多个字符
    • **: 匹配零个或多个路径
  • method 指定请求的 HTTP 方法(GET、POST、PUT、DELETE 等)。可以是一个 RequestMethod 枚举,也可以是一个 RequestMethod 数组。
  • params 指定请求必须包含的参数。可以是一个字符串数组,每个字符串表示一个参数条件(例如 "myParam""myParam=myValue""myParam!=myValue")。
  • headers 指定请求必须包含的请求头。可以是一个字符串数组,每个字符串表示一个请求头条件(例如 "myHeader""myHeader=myValue""myHeader!=myValue")。
  • consumes 指定请求的 Content-Type。例如 "application/json""text/plain"
  • produces 指定响应的 Content-Type。例如 "application/json""text/html"

3. @RequestMapping 的使用位置:

  • 类级别: 可以用在 Controller 类上,为该 Controller 中的所有方法定义一个公共的 URL 前缀。
  • 方法级别: (最常用)用在 Controller 方法上,定义该方法处理的具体请求。

4. @RequestMapping 的工作原理:

  1. 扫描和注册: Spring 容器启动时,会扫描所有带有 @Controller 注解的类。
  2. 解析 @RequestMapping 对于每个 Controller 类及其方法,Spring 会解析 @RequestMapping 注解,获取其属性值。
  3. 创建 RequestMappingInfo Spring 会根据 @RequestMapping 的属性值,创建一个 RequestMappingInfo 对象。RequestMappingInfo 包含了请求的匹配条件(URL、方法、参数、请求头等)。
  4. 注册映射关系: Spring 将 RequestMappingInfo 对象与对应的 Controller 方法(Handler Method)关联起来,并注册到 RequestMappingHandlerMapping 中。RequestMappingHandlerMapping 维护了一个映射表,用于存储请求与 Handler Method 之间的映射关系。
  5. 请求匹配: 当 Spring MVC 接收到一个 HTTP 请求时,DispatcherServlet 会使用 RequestMappingHandlerMapping 来查找匹配的 Handler Method。
    • RequestMappingHandlerMapping 会遍历所有已注册的 RequestMappingInfo,并根据请求的 URL、方法、参数、请求头等信息,与 RequestMappingInfo 中的匹配条件进行比较。
    • 如果找到匹配的 RequestMappingInfo,则返回对应的 HandlerExecutionChain(包含 Handler Method 和拦截器)。
  6. 方法调用: DispatcherServlet 使用 HandlerAdapter 调用匹配的 Handler Method,处理请求并返回结果。

5. 示例:

@Controller
@RequestMapping("/users") // 类级别的 @RequestMapping,定义公共 URL 前缀
public class UserController {
    
    

    @RequestMapping(value = "/{id}", method = RequestMethod.GET) // 匹配 GET /users/{id}
    public String getUserById(@PathVariable("id") Long id, Model model) {
    
    
        // ... 根据 id 获取用户信息 ...
        model.addAttribute("user", user);
        return "userView";
    }

    @RequestMapping(method = RequestMethod.POST, consumes = "application/json") // 匹配 POST /users,Content-Type 为 application/json
    public String createUser(@RequestBody User user, Model model) {
    
    
        // ... 创建用户 ...
        model.addAttribute("message", "User created successfully");
        return "success";
    }
     @RequestMapping(value = "/custom", method = RequestMethod.GET, params = "action=view")
      public String customView() {
    
    
        //...
      }
}

变体
为了简化,Spring 提供了几个基于 @RequestMapping 的变体:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

总结:

@RequestMapping 注解是 Spring MVC 中实现请求映射的核心机制。它通过一系列属性,定义了请求的匹配规则,并将请求映射到对应的 Controller 方法。Spring 容器启动时,会解析 @RequestMapping 注解,创建 RequestMappingInfo 对象,并将其注册到 RequestMappingHandlerMapping 中。当接收到请求时,RequestMappingHandlerMapping 会根据请求信息查找匹配的 Handler Method,从而实现请求的路由和处理。