在前后端分离的开发模式下,后端工程师每天都在和接口打交道。而写接口的第一步,就是准确接收前端传来的参数。
很多初学者在面对 @RequestParam、@PathVariable 和 @RequestBody 时经常会一头雾水,甚至因为用错了注解导致满屏的 400 Bad Request 或者接收到的数据全为 null。
今天,我们就来系统地梳理一下,在 Spring Boot 中到底该如何优雅地接收前端参数。
一、 GET 请求传参(查询数据)
GET 请求主要用于获取数据,参数通常拼接在 URL 中。我们有三种常见的接收方式:
1. 基础查询参数:@RequestParam
适用场景:前端通过 URL 问号拼接传参,例如 /api/stats?salesmanId=1001&month=2023-10。
@GetMapping("/api/stats")
public Result getStats(
@RequestParam("salesmanId") String salesmanId,
@RequestParam(value = "month", required = false, defaultValue = "2023-01") String month) {
System.out.println("业务员ID: " + salesmanId);
System.out.println("月份: " + month);
return Result.success();
}
💡 避坑指南:
- 默认情况下,被
@RequestParam修饰的参数是必填的。如果前端不传,会直接报错 400。 - 如果该参数是可选的,务必加上
required = false。 - 可以结合
defaultValue设置默认值,防止空指针异常。
2. 多参数对象接收(推荐)
适用场景:GET 请求的查询条件非常多(如分页查询、多条件筛选),全写在方法参数里不仅代码冗长,还难以维护。
技巧:直接使用对象(DTO)接收,不需要加任何注解!Spring Boot 会自动将 URL 中的参数映射到实体类的同名属性上。
定义 DTO:
@Data
public class StatsQueryDTO {
private String salesmanId;
private String month;
private Integer pageNum;
private Integer pageSize;
}
Controller:
@GetMapping("/api/stats/list")
public Result getStatsList(StatsQueryDTO queryDTO) {
System.out.println("业务员ID: " + queryDTO.getSalesmanId());
return Result.success();
}
3. RESTful 风格路径参数:@PathVariable
适用场景:参数作为 URL 路径的一部分,表达层级或具体资源的定位。例如 /api/salesman/1001。
@GetMapping("/api/salesman/{salesmanId}")
public Result getSalesmanDetail(@PathVariable("salesmanId") String salesmanId) {
System.out.println("查询的业务员ID: " + salesmanId);
return Result.success();
}
二、 POST / PUT 请求传参(提交数据)
POST 和 PUT 请求主要用于新增或修改数据,这类请求通常带有请求体(Body),用于传递复杂的 JSON 数据。
核心注解:@RequestBody
适用场景:前端将参数放在 HTTP 报文的 Body 中,并以 JSON 格式(Content-Type: application/json)提交。
前端发送的 JSON 数据:
{
"salesmanId": "1001",
"name": "张三",
"department": "销售一部",
"skills": ["Java", "Spring Boot"]
}
Controller 接收:
@PostMapping("/api/salesman/add")
public Result addSalesman(@RequestBody SalesmanDTO salesmanDTO) {
System.out.println("收到业务员姓名: " + salesmanDTO.getName());
// 插入数据库逻辑...
return Result.success();
}
💡 避坑指南:
- 一个 HTTP 请求只有一个 Body,所以一个方法里只能有一个
@RequestBody。 - 如果你发现 POST 请求接收到的对象属性全是
null,大概率是忘了加@RequestBody注解,导致 Spring 尝试用 URL 参数去绑定对象。
三、 进阶:请求头参数获取
获取请求头:@RequestHeader
适用场景:获取前端放在 Request Header 中的通用数据,最典型的就是 Token 鉴权。
@GetMapping("/api/protected/data")
public Result getProtectedData(@RequestHeader("Authorization") String token) {
System.out.println("当前用户的Token: " + token);
return Result.success();
}
四、 总结与速查表(建议收藏)
为了方便大家日常开发,我总结了这张传参黄金法则速查表:
| 请求方式 | 前端传参位置 | 后端接收注解 | 常见场景 |
|---|---|---|---|
| GET | 在 URL ? 后拼接 (?id=1&name=A) | @RequestParam 或 直接用对象接收 | 列表查询、条件检索、导出报表 |
| GET | 在 URL 路径中间 (/user/1001) | @PathVariable | 根据主键 ID 查询详情 |
| POST/PUT | 在请求体 (Body) 中传 JSON | @RequestBody | 表单提交、新增、修改、复杂对象嵌套 |
| 通用 | 在请求头中 (Header) | @RequestHeader | 获取 Token、App版本号、设备信息 |
🛑 终极警告:千万不要在 GET 请求中使用 @RequestBody!
虽然某些 HTTP 客户端(如 Postman)允许你在 GET 请求里塞入 Body,但在 HTTP 规范中这是不标准的。许多网关(如 Nginx)、代理服务器或浏览器可能会直接丢弃 GET 请求的 Body,导致线上环境参数丢失。
记住:查询用 GET + URL 传参,提交/修改用 POST/PUT + @RequestBody。
希望这篇文章能帮你理清 Spring Boot 的参数绑定机制,写出更健壮的接口。如果有疑问,欢迎在评论区探讨!