@RequestMapping, @GetMapping, @PostMapping 等注解的区别
@RequestMapping是通用请求映射,而@GetMapping、@PostMapping等是其派生注解,作为特定HTTP方法的快捷方式,能让代码更简洁明确。
这是一个在 Spring MVC / Spring Boot 开发中非常核心且常见的问题。下面我将为你详细解释 @RequestMapping, @GetMapping, @PostMapping 等注解的区别。
总结(一览表)
| 注解 | HTTP 方法 | 主要用途 |
|---|---|---|
@RequestMapping |
所有 (GET, POST, PUT, DELETE...) | 通用的请求映射,可以指定任何HTTP方法 |
@GetMapping |
GET | 获取/查询资源 |
@PostMapping |
POST | 创建新资源 |
@PutMapping |
PUT | 完整更新一个已存在的资源 |
@DeleteMapping |
DELETE | 删除一个资源 |
@PatchMapping |
PATCH | 部分更新一个已存在的资源 |
详细解释
1. @RequestMapping:最通用的“老大哥”
@RequestMapping 是最基础、最通用的请求映射注解。它可以用于类和方法上。
特点:
- 灵活性最高:你可以通过
method属性来指定它处理哪种或哪些 HTTP 请求方法(GET, POST 等)。如果不指定method,它会匹配所有的 HTTP 请求方法。 - 既可用于类,也可用于方法:
- 用在类上:定义一个基础的 URL 路径(URL 前缀),这个类中所有方法的映射路径都会在这个前缀之下。
- 用在方法上:定义该方法具体的访问路径和请求方式。
示例:
@RestController
@RequestMapping("/api/users") // 类级别:所有请求都在 /api/users 路径下
public class UserController {
// 传统方式:需要明确指定 method = RequestMethod.GET
@RequestMapping(method = RequestMethod.GET)
public List<User> getAllUsers() {
// ... 返回所有用户
}
// 传统方式:处理 POST 请求
@RequestMapping(method = RequestMethod.POST)
public User createUser(@RequestBody User user) {
// ... 创建用户
}
// 处理多个 HTTP 方法
@RequestMapping(value = "/{id}/status", method = {RequestMethod.GET, RequestMethod.POST})
public String getUserStatus(@PathVariable String id) {
// ... 这个方法既可以 GET 也可以 POST
}
}
缺点:代码可读性稍差,需要多写一个 method 属性,显得有些冗余。
2. @GetMapping, @PostMapping 等:更具体的“快捷方式”
从 Spring 4.3 版本开始,为了简化开发和提高代码可读性,引入了一系列组合注解(Composed Annotation)。@GetMapping, @PostMapping 等就是 @RequestMapping 的派生注解。
它们本质上是特定化的 @RequestMapping。
例如,@GetMapping 的源码是这样的:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET) // <-- 核心在这里!
public @interface GetMapping {
// ...
}
可以看到,@GetMapping 本身就是一个被 @RequestMapping(method = RequestMethod.GET) 注解的注解。
这些新注解的共同优点:
- 代码更简洁:无需再写
method = ...。 - 意图更明确:一眼就能看出这个方法是用来处理哪种 HTTP 请求的,大大提高了代码的可读性和可维护性。
- 减少错误:避免了忘记指定
method属性而导致的安全隐患(例如,一个本应只用于查询的接口,却能被 POST 请求访问)。
@GetMapping
专门用于处理 HTTP GET 请求,通常用于获取/查询数据。
@RestController
@RequestMapping("/api/users")
public class UserController {
// 等价于 @RequestMapping(value = "/{id}", method = RequestMethod.GET)
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
// ... 根据 id 查询用户
}
}
@PostMapping
专门用于处理 HTTP POST 请求,通常用于创建新的资源。
@RestController
@RequestMapping("/api/users")
public class UserController {
// 等价于 @RequestMapping(method = RequestMethod.POST)
@PostMapping
public User createUser(@RequestBody User newUser) {
// ... 创建新用户并返回
}
}
@PutMapping
专门用于处理 HTTP PUT 请求,通常用于完整更新一个已存在的资源(客户端需要提供该资源的全部信息)。
@RestController
@RequestMapping("/api/users")
public class UserController {
// 等价于 @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
// ... 根据 id 完整更新用户信息
}
}
@DeleteMapping
专门用于处理 HTTP DELETE 请求,通常用于删除一个资源。
@RestController
@RequestMapping("/api/users")
public class UserController {
// 等价于 @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
// ... 根据 id 删除用户
return ResponseEntity.noContent().build();
}
}
@PatchMapping
专门用于处理 HTTP PATCH 请求,通常用于部分更新一个已存在的资源(客户端只需要提供需要修改的字段)。
@RestController
@RequestMapping("/api/users")
public class UserController {
// 等价于 @RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
@PatchMapping("/{id}")
public User partialUpdateUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
// ... 根据 id 和 updates map 来局部更新用户信息
}
}
结论与最佳实践
优先使用新注解:在现代 Spring 开发中,强烈推荐使用
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping,@PatchMapping。它们能让你的代码更清晰、更安全、更符合 RESTful 风格。@RequestMapping的使用场景:- 类级别映射:依然是用于在 Controller 类上定义 URL 前缀的最佳选择。
- 处理多种 HTTP 方法:当你需要一个方法同时处理多种类型的 HTTP 请求时(虽然这种情况比较少见),
@RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})是唯一的选择。 - 兼容旧项目:在维护一些老版本的 Spring 项目时,你会经常看到它。
总而言之,把 @GetMapping 等看作是 @RequestMapping 的现代化、专业化的“快捷键”。平时写代码直接用这些“快捷键”,只有在特殊情况下才去使用功能更全面但稍显繁琐的 @RequestMapping。