GetMapping
本章紧接
@RequestMapping的核心机制。在实际开发中,查询操作是最频繁的 HTTP 请求类型。Spring 4.3 引入的@GetMapping是@RequestMapping(method = RequestMethod.GET)的语义化简写,它让代码更简洁、意图更清晰。理解@GetMapping,就掌握了 Spring MVC 处理只读查询请求的标准方式。
定义与作用
@GetMapping 是 Spring 4.3 引入的方法级组合注解,它的职责可以用一句话概括:声明一个方法只处理 HTTP GET 请求,用于读取或查询资源。
@GetMapping 的源码定义:
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {
// 继承 @RequestMapping 的所有属性:value, params, headers, consumes, produces
}
它与 @RequestMapping(method = RequestMethod.GET) 完全等价,但语义更明确:
- 看到
@GetMapping,立刻知道这是"查询"操作 - 看到
@RequestMapping(method = RequestMethod.GET),需要多读几个单词才能确认
GET 请求的语义
在 HTTP 协议中,GET 方法的语义是获取资源,具有以下特征:
- 安全:多次执行不会改变服务器状态
- 幂等:多次执行结果相同
- 可缓存:浏览器和代理可以缓存 GET 响应
- 参数在 URL 中:通过查询字符串(query string)传递参数
核心原理
@GetMapping 在请求链中的位置
图解:@GetMapping 的完整处理流程与 @RequestMapping 完全一致,区别只在 HandlerMapping 匹配时会额外检查 HTTP 方法是否为 GET。
@GetMapping 与 @RequestMapping(method=GET) 的等价关系
适用位置与常用属性
@GetMapping 只能标注在方法上,继承 @RequestMapping 的所有属性:
| 属性 | 类型 | 作用 | 示例 |
|---|---|---|---|
value / path | String[] | URL 路径映射 | "/employees"、"/{id}" |
params | String[] | 约束请求参数 | "department" |
headers | String[] | 约束请求头 | "X-Api-Version=2" |
produces | String[] | 约束响应 Content-Type | "application/json" |
注意:@GetMapping 已经固定了 method = GET,因此不需要(也不能)再写 method 属性。同时,GET 请求通常没有请求体,所以 consumes 属性很少使用。
完整示例
场景
飞翔科技的员工管理系统需要支持多种查询场景:列表查询、单条查询、条件查询。后端工程师小崔使用 @GetMapping 实现所有只读接口。
控制器代码
package com.feixiang.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/employees")
public class EmployeeController {
// 容器已注入该 Bean,本教程不展开 Service 实现
@Autowired
private EmployeeService employeeService;
// 查询所有员工
@GetMapping
public List<Employee> listAll() {
return employeeService.findAll();
}
// 根据 ID 查询单个员工
@GetMapping("/{id}")
public Employee getById(@PathVariable Long id) {
return employeeService.findById(id);
}
// 按部门查询
@GetMapping(params = "department")
public List<Employee> listByDepartment(@RequestParam String department) {
return employeeService.findByDepartment(department);
}
// 搜索员工(按姓名模糊匹配)
@GetMapping("/search")
public List<Employee> search(@RequestParam String name) {
return employeeService.findByNameLike(name);
}
}
HTTP 请求示例 1:查询员工列表
curl -X GET http://localhost:8080/employees \
-H "Accept: application/json"
实际响应:
[
{
"id": 1001,
"name": "张伟",
"department": "技术部",
"position": "高级工程师"
},
{
"id": 1002,
"name": "李娜",
"department": "市场部",
"position": "市场经理"
},
{
"id": 1003,
"name": "王强",
"department": "技术部",
"position": "初级工程师"
}
]
分析:
@GetMapping声明此方法只处理 GET 请求- 如果发送 POST 请求到
/employees,会返回 405 Method Not Allowed - 返回
List<Employee>,由@RestController自动序列化为 JSON 数组
HTTP 请求示例 2:查询单个员工
curl -X GET http://localhost:8080/employees/1001 \
-H "Accept: application/json"
实际响应:
{
"id": 1001,
"name": "张伟",
"department": "技术部",
"position": "高级工程师",
"email": "zhangwei@feixiang.com",
"phone": "13800138001"
}
分析:
@GetMapping("/{id}")配合@PathVariable提取 URL 路径变量id=1001被自动转换为Long类型- 如果员工不存在,Service 层返回 null,可配合
@ResponseStatus(HttpStatus.NOT_FOUND)抛出 404
易错场景与面试考点
误区一:用 @GetMapping 处理非幂等操作
错误写法:
@GetMapping("/delete/{id}")
public void deleteEmployee(@PathVariable Long id) {
employeeService.delete(id); // 严重错误!
}
纠正:GET 请求应该是安全和幂等的,不应该修改服务器状态。删除操作必须使用 @DeleteMapping(或 @PostMapping)。此外,浏览器预加载、爬虫抓取都可能意外触发 GET 请求,导致数据被误删。
// 正确做法
@DeleteMapping("/{id}")
public void deleteEmployee(@PathVariable Long id) {
employeeService.delete(id);
}
误区二:@GetMapping 方法使用 @RequestBody
错误写法:
@GetMapping("/search")
public List<Employee> search(@RequestBody SearchCriteria criteria) {
// ...
}
纠正:HTTP GET 请求没有请求体(虽然某些客户端可以发送 GET 请求体,但服务器通常忽略它)。Spring MVC 的 @RequestBody 在 GET 请求下行为不可预期,应该使用 @RequestParam 或 @ModelAttribute:
@GetMapping("/search")
public List<Employee> search(
@RequestParam(required = false) String name,
@RequestParam(required = false) String department) {
return employeeService.search(name, department);
}
面试高频:@GetMapping 与 @RequestMapping 的区别
标准回答:
@GetMapping是@RequestMapping(method = RequestMethod.GET)的组合注解,两者功能完全等价@GetMapping语义更清晰,看到注解就知道是查询操作@GetMapping只能标注在方法上,且已经固定了 HTTP 方法为 GET- Spring 4.3+ 推荐使用
@GetMapping、@PostMapping等派生注解替代冗长的@RequestMapping - GET 请求应该是安全和幂等的,只用于读取资源,不用于修改状态
小结
@GetMapping 是 Spring MVC 处理 HTTP GET 请求的语义化注解,它是 @RequestMapping(method = RequestMethod.GET) 的简写形式。GET 请求用于读取资源,具有安全和幂等特性。在现代 Spring MVC 项目中,@GetMapping 是查询接口的标准写法。
本章与全局的关系:本章讲解了只读查询请求的映射注解。下一章"PostMapping"将讲解用于创建资源的 @PostMapping,以及 GET 与 POST 的核心区别。