# 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 直接用实体类接收,不加任何注解

八、开发实践建议

  1. 统一规范:项目内约定好 GET 用 Query + 实体类,POST/PUT 用 JSON + @RequestBody,避免风格混乱。
  2. 优先使用实体类:参数超过 3 个时,建议封装为实体类,提高代码可读性和可维护性。
  3. 参数校验:配合 @Valid + @NotNull 等注解做参数校验,减少业务层判空代码。
  4. 日志打印:在 Controller 层打印接收到的参数,方便联调排查问题。

总结

Spring Boot 接收参数的方式虽然多样,但总结下来无非是参数来源注解选择的排列组合。记住三个核心注解:

  • @PathVariable → URL 路径中的值
  • @RequestParam → URL 问号后面的值
  • @RequestBody → 请求体中的 JSON

掌握这三个,再加上实体类自动绑定,就能覆盖 95% 以上的开发场景。

如果你在实践中有任何疑问,欢迎在评论区留言交流!