
直接接收数组(Array)
1. GET 请求:通过查询参数传多个同名参数
@GetMapping("/delete")
public String deleteByIds(String[] ids) {
// 请求:/delete?ids=1&ids=2&ids=3
// ids = ["1", "2", "3"]
System.out.println("要删除的ID数量: " + ids.length);
return "OK";
}
✅ 无需任何注解!Spring 会自动将多个
ids参数合并为数组。
2. POST 表单:多个同名 input 字段
HTML 表单:
Controller:
@PostMapping("/submit-tags")
public String submitTags(String[] tags) {
// tags = ["Java", "Spring", "Boot"]
return "收到标签: " + Arrays.toString(tags);
}
✅ 同样无需注解,Spring 自动绑定。
3. 支持的基本类型数组
| 类型 | 示例 |
|---|---|
String[] | ✅ 最常用 |
int[] | ✅ 自动转换(如 ?ids=1&ids=2 → [1, 2]) |
Integer[] | ✅ 包装类型也支持 |
long[], double[] 等 | ✅ 基本数值类型都支持 |
⚠️ 注意:如果传入非数字字符串(如
?ids=abc),会抛出TypeMismatchException。
直接接收集合(List / Set)
1. 使用 List<String>(最常见)
@GetMapping("/search")
public String searchByTags(List tags) {
// 请求:/search?tags=hot&tags=new
// tags = ["hot", "new"]
return "标签: " + tags;
}
✅ 无需
@RequestParam!Spring 自动识别并绑定。
2. 使用 List<Integer>(自动类型转换)
@GetMapping("/batch-update")
public String batchUpdate(List userIds) {
// 请求:/batch-update?userIds=101&userIds=102
// userIds = [101, 102]
return "用户ID列表: " + userIds;
}
3. 使用 Set<String>(自动去重)
@GetMapping("/unique-tags")
public String uniqueTags(Set tags) {
// 请求:/unique-tags?tags=A&tags=B&tags=A
// tags = ["A", "B"] (顺序可能变化)
return "去重后标签: " + tags;
}
Set会自动去重,但不保证顺序(可用LinkedHashSet保持插入顺序,但需自定义绑定)。
GET 与 POST 都支持!
无论是:
- GET 查询参数:
?id=1&id=2 - POST 表单参数:
Content-Type: application/x-www-form-urlencoded,多个id=1&id=2
Spring 都能正确绑定到数组或 List。
注意事项与避坑指南
| 问题 | 说明 |
|---|---|
| 参数名必须一致 | 方法参数名(如 ids)必须和请求参数名一致 |
| 空参数处理 | 如果没传参数,数组/集合为 null(不是空数组!) |
| 建议初始化或判空 | 使用前检查 if (ids != null) |
| 不支持泛型嵌套 | 不能直接接收 List<List<String>>(需包装对象或用 JSON) |
| JSON 请求不适用 | 此方式仅适用于表单/查询参数;JSON 必须用 @RequestBody |
通过表单 / 查询参数接收复杂对象
✅ 1. 接收数组(Array)
实体类:
public class UserForm {
private String name;
private String[] hobbies; // 数组
// getter/setter
}
表单字段命名(HTML 或 curl):
或 URL:
?name=张三&hobbies=读书&hobbies=跑步
✅ Spring 会自动将多个 hobbies 合并为数组。
✅ 2. 接收 List 集合
实体类:
public class UserForm {
private List tags;
private List scores;
// getter/setter(必须有!)
}
表单命名(两种方式):
方式一:直接同名(推荐)
✅ Spring 能自动识别为 List。
方式二:带索引(兼容旧浏览器)
两种都支持,但方式一更简洁。
✅ 3. 接收 Set 集合
public class UserForm {
private Set permissions = new LinkedHashSet<>();
// 必须初始化!否则可能为 null
public Set getPermissions() { return permissions; }
public void setPermissions(Set permissions) { this.permissions = permissions; }
}
表单:
⚠️ 注意:Set 无序且去重,如果传入重复值,只会保留一个。
✅ 4. 接收嵌套对象
实体类:
public class UserForm {
private String name;
private Address address; // 嵌套对象
// getter/setter
}
public class Address {
private String city;
private String street;
// getter/setter
}
表单命名(使用点号 .):
✅ Spring 会自动创建 Address 实例并赋值。
❗ 要求:
UserForm必须有setAddress(Address)方法,且Address有默认构造函数。
✅ 5. 接收 List<对象>
这是最复杂的场景!
实体类:
public class OrderForm {
private List- items;
// getter/setter
}
public class Item {
private String name;
private Integer quantity;
// getter/setter
}
表单命名(必须带索引):
✅ Spring 会自动创建 List<Item> 并填充。
⚠️ 必须使用
[index]形式!不能写成items.name,否则无法识别为列表。
通过 JSON 请求体接收复杂对象(@RequestBody)
JSON 方式更简单、更强大,无需特殊命名,结构天然匹配。
✅ 示例:接收包含 List、Map、嵌套对象的 JSON
实体类:
public class ApiRequest { private String userId; private Listtags; private Set roles; private Map metadata; private List addresses; // getter/setter }
请求 JSON:
{
"userId": "U123",
"tags": ["hot", "new"],
"roles": ["admin", "user"],
"metadata": {
"source": "web",
"version": 2
},
"addresses": [
{ "city": "上海", "street": "南京路" },
{ "city": "深圳", "street": "华强北" }
]
}
Controller:
@PostMapping("/api")
public ResponseEntity handle(@RequestBody ApiRequest request) {
// 直接使用 request 对象
return ResponseEntity.ok(request);
}
✅ Jackson 会自动完成所有映射,包括泛型、嵌套、Map 的 value 类型推断。
优势:
- 无需关心字段命名格式
- 支持任意深度嵌套
- 自动处理 null、空集合等边界情况
常见问题与避坑指南
| 问题 | 原因 | 解决方案 |
|---|---|---|
| List 为 null | 实体类未初始化 | 在声明时初始化:private List<String> tags = new ArrayList<>(); |
| 嵌套对象绑定失败 | 缺少 setter 或默认构造函数 | 确保有 setXxx() 和无参构造 |
| 表单中 List 不生效 | 未使用 [index] 格式 | 对象列表必须用 items[0].name |
| GET 请求传 List | URL 中 ?tags=A&tags=B | 可以!Spring 支持多值查询参数绑定到 List |
| Map 接收表单参数 | 表单字段如 meta[key]=value | 支持!但需用 @RequestParam Map<String, String>,不支持嵌套 Map |
| JSON 中数字变 Double | Jackson 默认行为 | 配置 DeserializationFeature.USE_LONG_FOR_INTS 或用 JsonNode 手动解析 |
最佳实践建议
优先使用 JSON +
@RequestBody
结构清晰、支持完整、不易出错,适合现代前后端分离架构。表单场景谨慎使用复杂嵌套
如果必须用表单传 List<对象>,确保前端生成正确的[index].field名称。集合字段务必初始化
private Listitems = new ArrayList<>(); // 避免 NPE GET 请求慎用复杂对象
虽然支持 List 和简单对象,但 URL 长度有限,不适合传大量数据。
浙公网安备 33010602011771号