# Spring Boot 控制器接收参数全攻略(含单参/多参示例)
> 在 Spring Boot 开发中,Controller 层接收前端参数是最基础也最容易踩坑的地方。本文用最直观的方式,把 GET/POST 请求下的**单参数**、**多参数**、**混合参数**、**数组集合**场景一网打尽,附带代码示例和避坑指南,建议收藏。
---
## 一、参数接收方式概览
| 参数来源 | 推荐注解 | 适用场景 |
| :--- | :--- | :--- |
| Query String(`?key=value`) | `@RequestParam` | GET 搜索、分页、筛选 |
| URL 路径占位符(`/{id}`) | `@PathVariable` | RESTful 风格详情接口 |
| JSON 请求体(Body) | `@RequestBody` | POST/PUT 新增、更新 |
| Form 表单提交 | 无注解 / 实体类 | 传统表单场景 |
| 请求头(Header) | `@RequestHeader` | Token 鉴权、传递固定参数 |
---
## 二、GET 请求参数接收
### 1. 单个参数
**方式一:路径占位符(RESTful)**
```java
// 前端请求:GET /user/1001
@GetMapping("/user/{id}")
public String getById(@PathVariable Long id) {
return "查询单个用户ID:" + id;
}
方式二:Query 参数(? 传参)
// 前端请求:GET /user?id=1001
@GetMapping("/user")
public String getById2(@RequestParam Long id) {
return "查询单个用户ID:" + id;
}
2. 多个参数
写法一:多个 @RequestParam 逐一列出
// 前端请求:GET /user?name=Jack&age=25&city=北京
@GetMapping("/user")
public String getUsers(@RequestParam String name,
@RequestParam Integer age,
@RequestParam String city) {
return "姓名:" + name + ",年龄:" + age + ",城市:" + city;
}
写法二:使用 Map 接收(参数不固定时)
// 前端请求:GET /user?name=Jack&age=25&hobby=football
@GetMapping("/user/map")
public String getUsersByMap(@RequestParam Map<String, String> params) {
return "所有参数:" + params.toString();
// 输出:{name=Jack, age=25, hobby=football}
}
写法三:使用实体类接收(最优雅,强烈推荐)
// 前端请求:GET /user?name=Jack&age=25&city=北京
@GetMapping("/user/entity")
public String getUsersByEntity(UserQuery query) {
return "姓名:" + query.getName() + ",年龄:" + query.getAge() + ",城市:" + query.getCity();
}
// 对应的实体类(需有 getter/setter)
public class UserQuery {
private String name;
private Integer age;
private String city;
// 省略 getter/setter...
}
三、POST 请求参数接收
1. 单个参数(JSON)
// 前端请求:POST /user
// Body: {"name": "Jack"}
@PostMapping("/user")
public String createUser(@RequestBody User user) {
return "创建用户:" + user.getName();
}
2. 多个参数(JSON 对象)
// 前端请求:POST /user
// Body: {"name":"Jack", "age":25, "email":"jack@qq.com", "address":"北京"}
@PostMapping("/user")
public String createUserFull(@RequestBody User user) {
return "姓名:" + user.getName() +
",年龄:" + user.getAge() +
",邮箱:" + user.getEmail() +
",地址:" + user.getAddress();
}
// 对应的实体类
public class User {
private String name;
private Integer age;
private String email;
private String address;
// 省略 getter/setter...
}
3. 不想建实体类?用 Map 接收 JSON
// 前端请求:POST /user/map
// Body: {"name":"Jack", "age":25, "score":98.5}
@PostMapping("/user/map")
public String createUserByMap(@RequestBody Map<String, Object> params) {
return "所有参数:" + params.toString();
// 输出:{name=Jack, age=25, score=98.5}
}
四、混合场景:路径 + Query + Body 同时使用
实际开发中,一个接口可能同时包含多种参数来源,这是完全合法的:
// 前端请求:PUT /order/1001?status=PAID
// Body: {"productName": "手机", "price": 5999}
@PutMapping("/order/{orderId}")
public String updateOrder(@PathVariable Long orderId, // 路径参数
@RequestParam String status, // Query 参数
@RequestBody Order order) { // Body 参数
return "订单ID:" + orderId +
",状态:" + status +
",商品:" + order.getProductName() +
",价格:" + order.getPrice();
}
五、数组 / 集合参数接收
GET 请求:多个相同参数名
// 前端请求:GET /users?ids=1001&ids=1002&ids=1003
@GetMapping("/users")
public String getUsers(@RequestParam List<Long> ids) {
return "用户ID列表:" + ids.toString(); // 输出:[1001, 1002, 1003]
}
POST 请求:JSON 数组
// 前端请求:POST /users/batch
// Body: [1001, 1002, 1003]
@PostMapping("/users/batch")
public String batchGetUsers(@RequestBody List<Long> ids) {
return "批量查询ID:" + ids.toString();
}
六、速查对照表(单参 vs 多参)
| 场景 | 单个参数示例 | 多个参数示例 |
|---|---|---|
| GET - 路径占位符 | @PathVariable Long id |
多个占位符:/{id}/{name} 对应多个 @PathVariable |
| GET - Query 参数 | @RequestParam Long id |
@RequestParam String name, Integer age 或实体类 |
| POST - JSON Body | @RequestBody User user(实体类只有一个字段) |
@RequestBody User user(实体类有多个字段)或 Map |
| 参数不固定 | 建议用 Map |
@RequestParam Map 或 @RequestBody Map |
七、避坑指南(重点!)
| 常见错误 | 正确做法 |
|---|---|
POST 传 JSON 却用 @RequestParam 接收 |
改为 @RequestBody |
GET 传 Query 参数却用 @RequestBody |
GET 没有 Body,改为 @RequestParam 或实体类无注解 |
| 参数名与前端字段名不一致导致绑定失败 | 使用 @RequestParam("前端字段名") 或 @JsonProperty |
| 前端少传参数导致 400 错误 | 加 required = false 或设置 defaultValue |
| 时间格式传参报错 | 实体类字段加 @DateTimeFormat(pattern = "yyyy-MM-dd") |
POST 表单提交(application/x-www-form-urlencoded)误用 @RequestBody |
直接用实体类接收,不加任何注解 |
八、开发实践建议
- 统一规范:项目内约定好 GET 用 Query + 实体类,POST/PUT 用 JSON +
@RequestBody,避免风格混乱。 - 优先使用实体类:参数超过 3 个时,建议封装为实体类,提高代码可读性和可维护性。
- 参数校验:配合
@Valid+@NotNull等注解做参数校验,减少业务层判空代码。 - 日志打印:在 Controller 层打印接收到的参数,方便联调排查问题。
总结
Spring Boot 接收参数的方式虽然多样,但总结下来无非是参数来源和注解选择的排列组合。记住三个核心注解:
@PathVariable→ URL 路径中的值@RequestParam→ URL 问号后面的值@RequestBody→ 请求体中的 JSON
掌握这三个,再加上实体类自动绑定,就能覆盖 95% 以上的开发场景。
如果你在实践中有任何疑问,欢迎在评论区留言交流!

已有 0 条评论