新手必懂的SpringBoot接口传参全攻略:查询参数/路径参数/JSON 参数
作者:暗暗别做白日梦
- 为什么有的接口直接写 DTO 就能接收参数?
@PathVariable、@RequestParam、@RequestBody到底什么时候用?- GET 请求能不能传 JSON?路径参数和查询参数怎么区分?
- 省市区联动接口该如何设计传参和返回值?
本文结合真实业务代码,用最通俗的语言,把 SpringBoot 接口传参的所有核心知识点讲透,新手看完直接上手!
一、SpringBoot 三大传参方式(核心必背)
SpringBoot 接口传参分为 3 种标准场景,对应不同的请求类型和业务需求,严格遵循 HTTP 协议规范。
URL 查询参数(? 后面的参数)→ 最常用
适用场景:GET 请求、查询列表、多条件筛选、省市区联动等获取数据的场景接收写法:直接写 DTO / 实体类,无需任何注解,Spring 自动封装参数前端传参:/api/linkage?parentId=0&level=1
// 你的省市区联动接口(标准查询参数写法)
@GetMapping("/linkage")
public ApiResponse<List<CountryAreaOptionDTO>> linkage(
@Valid CountryAreaLinkageQueryDTO request // 自动封装所有查询参数
) {
return ApiResponse.success(countryAreaDOService.queryLinkage(request));
}
路径参数(/xxx/{id})→ 操作单个资源
适用场景:根据唯一 ID查询 / 删除 / 修改单个资源(RESTful 规范)接收写法:必须加 @PathVariable 注解前端传参:/api/area/1001
// 查询单个地区详情(路径参数写法)
@GetMapping("/area/{areaId}")
public ApiResponse<CountryAreaDO> getAreaById(
@PathVariable Long areaId // 接收路径中的ID
) {
return ApiResponse.success(countryAreaDOService.getById(areaId));
}
JSON 请求体参数 → 增 / 改数据
适用场景:POST/PUT 请求、提交大量数据、复杂对象参数接收写法:必须加 @RequestBody 注解前端传参:JSON 格式放在请求体中
// 新增地区(JSON参数写法)
@PostMapping("/area/save")
public ApiResponse<Boolean> saveArea(
@RequestBody CountryAreaDO areaDO // 接收JSON参数
) {
return ApiResponse.success(countryAreaDOService.save(areaDO));
}
三大传参方式对比表
表格
| 传参方式 | 请求类型 | 核心注解 | 业务场景 |
|---|---|---|---|
| URL 查询参数 | GET | 无(直接写 DTO) | 查询列表、筛选、联动 |
| 路径参数 | GET/DELETE | @PathVariable | 单资源查 / 删 / 改 |
| JSON 请求体 | POST/PUT | @RequestBody | 新增、修改、提交复杂数据 |
二、关键区分:DTO 自动封装 vs @RequestParam
新手最容易混淆:加不加 @RequestParam 的区别,一句话搞定:
- 不加注解:自动把前端所有参数封装成 DTO 对象
- 加
@RequestParam:只提取前端的单个参数
不加注解 → 自动封装 DTO
前端传多个参数,Spring 自动匹配字段,封装成对象:
// 前端:?parentId=0&level=1 → 自动封装进DTO
@GetMapping("/linkage")
public ApiResponse linkage(CountryAreaLinkageQueryDTO request) {}
加@RequestParam→ 提取单个参数
只需要前端的某一个参数,单独接收:
// 只接收 provinceId 这一个参数
@GetMapping("/cities")
public ApiResponse cities(@RequestParam Long provinceId) {}
禁忌
千万不要给 DTO 加 @RequestParam,会直接报错!
三、核心铁律:GET 请求绝对不用 JSON
这是 HTTP 协议的固定规则,企业开发强制遵守:
- GET 请求没有请求体,强行传 JSON 会被服务器丢弃
- GET 参数只能放在 URL 中,适合查询、非敏感数据
- 只有 POST/PUT 才用 JSON 参数
四、实战案例:省市区多级联动接口设计
结合你的业务需求,不修改数据库、不新增字段,纯后端实现省市区联动,完整方案如下:
前端传参规则
- 查省份:
/provinces(parentId=0) - 查城市:
/cities?provinceId=xxx - 查区县:
/districts?cityId=xxx - 通用接口:
/linkage?parentId=xxx
后端核心代码(层级判断逻辑)
不靠数据库 level 字段,纯通过父 ID 判断省 / 市 / 区:
// 核心联动查询方法
public List<CountryAreaOptionDTO> queryLinkage(Long parentId) {
// 1. 查询当前层级数据
List<CountryAreaDO> areas = parentId == null
? list(Wrappers.<CountryAreaDO>lambdaQuery().isNull(CountryAreaDO::getPid))
: list(Wrappers.<CountryAreaDO>lambdaQuery().eq(CountryAreaDO::getPid, parentId));
// 2. 获取所有父ID集合(判断是否有子节点)
Set<Long> parentIds = list(Wrappers.<CountryAreaDO>lambdaQuery().isNotNull(CountryAreaDO::getPid))
.stream().map(CountryAreaDO::getPid).collect(Collectors.toSet());
// 3. 自动判断层级:省/市/区
return areas.stream().map(area -> toOption(area, level, parentIds)).toList();
}
// 层级判断规则
parentId == null ? 省份 : parentIds.contains(area.getId()) ? 市 : 区
3. 前端接收 DTO(标准返回值)
@Data
public class CountryAreaOptionDTO {
private Long id; // 下一级查询的parentId
private String name; // 前端展示名称
private String level; // 层级编码
private String levelDesc; // 省/市/区
private boolean hasChildren; // 是否有子节点
}
五、新手常见问题:为什么项目不能本地启动?
很多新手发现:有的项目能启动,有的不能,核心原因只有一个:项目运行环境 / 配置不满足,和项目本身无关!
最常见 4 个启动失败原因
- 端口被占用:8080 端口被其他软件占用
- 数据库连接失败:MySQL 未启动、账号密码错误
- Maven 依赖未下载完:代码全红,编译失败
- 配置文件语法错误:yml 缩进错误
10 秒排查方法
看控制台第一行红字:
- 含
port→ 换端口 - 含
MySQL→ 检查数据库 - 含
dependency→ 重新加载 Maven
六、新手必背口诀(记住永不踩坑)
- 查数据用 GET,参数放?后面,直接写 DTO
- 单资源查改删,用路径参数,加 @PathVariable
- 增改数据用 POST,传 JSON,加 @RequestBody
- 不加注解封 DTO,加注解取单个参数
- GET 不用 JSON,路径参数只传 ID
总结
本文覆盖了 SpringBoot 接口传参的所有核心知识点,结合省市区联动真实业务,从基础用法到实战设计,彻底解决新手传参困惑。
SpringBoot 传参没有复杂逻辑,严格遵循规范,结合业务场景选择对应的方式,就能写出规范、可维护的接口代码!
以上就是新手必懂的SpringBoot接口传参全攻略:查询参数/路径参数/JSON 参数的详细内容,更多关于SpringBoot接口传参的资料请关注脚本之家其它相关文章!
