spring boot 获取HTTP 请求参数

获取 HTTP 请求参数是非常常见的操作。无论你是做 REST API 还是传统 Web 表单,都需要从请求中提取数据。


🌟 一、总体分类:5 种常见参数来源

参数类型 说明 注解
1. 路径参数 URL 中的动态部分,如 /user/123 中的 123 @PathVariable
2. 查询参数 URL 问号后的参数,如 /search?name=张三 @RequestParam
3. 请求体(Body) POST/PUT 请求中发送的 JSON、XML、表单等数据 @RequestBody
4. 表单参数 HTML 表单提交的 application/x-www-form-urlencoded 数据 @RequestParam(或直接用对象)
5. 请求头(Header) Authorization: Bearer xxx @RequestHeader

🔹 1. 路径参数:@PathVariable

用于获取 URL 路径中的动态值。

✅ 示例:

复制代码
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
    return "用户ID是:" + id;
}
  • 请求:GET /user/1001
  • 结果:用户ID是:1001

⚠️ 注意:{id} 必须和 @PathVariable 的参数名一致,或显式指定:@PathVariable("id")


🔹 2. 查询参数:@RequestParam

用于获取 URL 中 ? 后面的参数(Query String)。

✅ 示例:

复制代码
@GetMapping("/search")
public String search(@RequestParam String keyword, 
                     @RequestParam(defaultValue = "10") int size) {
    return "搜索关键词:" + keyword + ",返回数量:" + size;
}
  • 请求:GET /search?keyword=手机&size=20
  • 结果:搜索关键词:手机,返回数量:20

📌 常用选项:

  • required = false:参数可选

  • defaultValue = "xxx":默认值(自动类型转换)

    @RequestParam(required = false, defaultValue = "1") int page

💡 如果参数名和方法参数名一致,@RequestParam 可省略(但建议保留,更清晰)。

参数如果多了,也可以绑定到实体上

1.定义查询参数实体类
复制代码
public class UserQuery {
    private String name;
    private Integer age;
    private String email;
    private Integer page = 1;      // 默认值
    private Integer size = 10;

    // 必须提供 getter/setter(Lombok 可简化)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    // ... 其他 getter/setter
}

💡 注意 :必须有 setter 方法,Spring 才能通过反射赋值。


2. Controller 中直接使用该实体(无需注解!)
复制代码
@GetMapping("/users")
public List<User> searchUsers(UserQuery query) {
    System.out.println("查询条件: " + query.getName() + ", 年龄: " + query.getAge());
    // 调用 service 查询...
    return userService.search(query);
}

关键点不需要加 @RequestParam@RequestBody

Spring 会自动将 ?name=张三&age=25&page=2 绑定到 UserQuery 对象。


3. 测试请求
复制代码
GET /users?name=张三&age=25&email=zhangsan@example.com&page=2&size=20

Spring 会自动创建 UserQuery 实例,并调用:

  • setName("张三")
  • setAge(25)
  • setEmail("zhangsan@example.com")
  • setPage(2)
  • setSize(20)

🔹 3. 请求体(JSON):@RequestBody

用于接收 POST/PUT 请求中的 JSON 数据(最常见于 REST API)。

✅ 示例:

复制代码
@PostMapping("/user")
public String createUser(@RequestBody User user) {
    return "创建用户:" + user.getName();
}

public class User {
    private String name;
    private int age;
    // getter/setter
}
  • 请求(Content-Type: application/json):

    复制代码
    POST /user
    {
      "name": "李四",
      "age": 25
    }
  • 结果:创建用户:李四

✅ Spring Boot 默认用 Jackson 自动把 JSON 转成 Java 对象。
❌ 不能用于 GET 请求(GET 没有请求体)。


🔹 4. 表单参数(传统 Web 表单)

HTML 表单提交的数据(Content-Type: application/x-www-form-urlencoded),Spring 会自动绑定到对象或参数。

方式一:用对象自动绑定(推荐)

复制代码
@PostMapping("/login")
public String login(UserForm form) { // 不需要注解!
    return "用户名:" + form.getUsername();
}

public class UserForm {
    private String username;
    private String password;
    // getter/setter
}

表单:

复制代码
<form action="/login" method="post">
  <input name="username" value="admin">
  <input name="password" value="123">
  <button type="submit">登录</button>
</form>

方式二:用 @RequestParam 一个个取

复制代码
@PostMapping("/login")
public String login(@RequestParam String username, 
                    @RequestParam String password) {
    // ...
}

💡 表单参数和查询参数都用 @RequestParam,Spring 会自动区分来源。

如果参数名和方法参数名一致,@RequestParam 可省略(但建议保留,更清晰)。


🔹 5. 请求头(Header):@RequestHeader

获取 HTTP 请求头中的信息,比如 Token、语言偏好等。

✅ 示例:

复制代码
@GetMapping("/profile")
public String profile(@RequestHeader("Authorization") String auth) {
    return "Token 是:" + auth;
}
  • 请求头:

    复制代码
    Authorization: Bearer abc123xyz
  • 结果:Token 是:Bearer abc123xyz

可选 + 默认值:

复制代码
@RequestHeader(value = "Accept-Language", defaultValue = "zh-CN") String lang

🔸 特殊情况:获取原始请求对象

如果你需要更底层的操作,可以直接注入:

复制代码
@GetMapping("/raw")
public void handle(HttpServletRequest request, 
                   HttpServletResponse response) {
    String ip = request.getRemoteAddr();
    // 直接操作 request/response
}

但一般不推荐,除非做特殊处理(如文件下载、自定义响应流)。


✅ 总结

参数类型 是否可省略注解 条件 示例
简单类型(String/int 等) ✅ 可省略 @RequestParam 参数名 = 请求参数名 String name
复杂对象(POJO) ✅ 可省略所有注解 表单/查询参数,字段名匹配 UserForm form
JSON 对象 不可省略 @RequestBody 必须显式声明 @RequestBody User user
路径变量 不可省略 @PathVariable 必须显式声明 @PathVariable Long id
请求头 不可省略 @RequestHeader 必须显式声明 @RequestHeader String token

使用 Map 接收请求参数

尤其适用于:

  • 参数结构动态不确定(比如第三方回调、表单字段不固定)
  • 不想定义专门的 POJO 类
  • 快速原型开发或调试

下面详细讲解 如何用 Map 接收各种请求参数,以及注意事项。


一、用 Map 接收表单或查询参数(最常见)

场景:application/x-www-form-urlencoded 或 URL 查询参数

复制代码
@PostMapping("/submit")
public String handleForm(@RequestParam Map<String, String> params) {
    // params 会自动包含所有表单字段
    String name = params.get("username");
    String email = params.get("email");
    return "收到参数: " + params;
}

✅ 请求(表单或 curl):

复制代码
curl -X POST http://localhost:8080/submit \
     -d "username=alice&email=a@example.com&age=25"

params = {username=alice, email=a@example.com, age=25}

🔍 关键点:

  • 必须加 @RequestParam
    如果写成 Map<String, String> params(无注解),Spring 会认为你想用 @RequestBody,从而报错。
  • 值类型是 String :所有参数值都会被转为字符串(即使传的是数字 "25")。
  • 支持多值吗 ? ❌ Map<String, String> 只取第一个值。如果需要多值,用 MultiValueMap(见下文)。

二、用 Map 接收 JSON 请求体(动态 JSON)

如果你收到的是 结构不固定的 JSON ,也可以用 Map 接收:

复制代码
@PostMapping("/dynamic-json")
public String handleJson(@RequestBody Map<String, Object> payload) {
    // payload 是解析后的 JSON 对象
    String name = (String) payload.get("name");
    Integer age = (Integer) payload.get("age");
    return "JSON 内容: " + payload;
}

✅ 请求:

复制代码
curl -X POST http://localhost:8080/dynamic-json \
     -H "Content-Type: application/json" \
     -d '{"name":"Bob","age":30,"tags":["java","spring"]}'

payload = {name=Bob, age=30, tags=[java, spring]}

🔍 关键点:

  • 必须加 @RequestBody
  • 值类型是 Object,可以是 StringNumberList、嵌套 Map
  • Spring 使用 Jackson 自动将 JSON 转为 Map<String, Object>

三、高级用法:接收多值参数(如 ?tag=A&tag=B

如果同一个参数名出现多次(如复选框),用 Map 会丢失数据。此时应使用 MultiValueMap

复制代码
@GetMapping("/search")
public String search(@RequestParam MultiValueMap<String, String> params) {
    List<String> tags = params.get("tag"); // 可能是 ["A", "B"]
    return "标签: " + tags;
}

✅ 请求:/search?tag=Java&tag=Springtags = ["Java", "Spring"]
💡 MultiValueMap 是 Spring 提供的接口,常用实现是 LinkedMultiValueMap


常见误区与注意事项

问题 正确做法
写成 Map params(无注解) ❌ Spring 无法判断来源,会报错
期望 Map<String, Integer> 自动转数字 ❌ 表单/查询参数中 Map 的值永远是 String
Map 接收 JSON 但忘记 @RequestBody ❌ 必须加 @RequestBody
Map 接收路径变量 ❌ 路径变量只能用 @PathVariable

完整示例代码

复制代码
@RestController
public class MapParamController {

    // 1. 接收表单/查询参数
    @PostMapping("/form-map")
    public Map<String, String> handleForm(@RequestParam Map<String, String> params) {
        return params;
    }

    // 2. 接收动态 JSON
    @PostMapping("/json-map")
    public Map<String, Object> handleJson(@RequestBody Map<String, Object> payload) {
        return payload;
    }

    // 3. 接收多值参数
    @GetMapping("/multi")
    public List<String> handleMulti(@RequestParam MultiValueMap<String, String> params) {
        return params.get("item");
    }
}

什么时候该用 Map

场景 推荐
参数结构固定、已知 ❌ 用 POJO(类型安全、可校验)
第三方回调(如支付通知) ✅ 用 Map 快速接收
前端传动态表单(字段不固定) ✅ 用 @RequestParam Map
调试或临时接口 ✅ 用 Map 省去定义类
需要参数校验(@Valid) Map 无法使用 Bean Validation

总结

请求类型 接收方式 注解
表单 / 查询参数 Map<String, String> @RequestParam
JSON 动态对象 Map<String, Object> @RequestBody
多值参数 MultiValueMap<String, String> @RequestParam

记住

  • 表单/查询 → @RequestParam Map
  • JSON → @RequestBody Map
  • 永远不要省略注解!

用好 Map,让你的接口更灵活;用好 POJO,让你的代码更健壮。根据场景选择即可!

相关推荐
Kina_C3 小时前
Apache HTTP Server 安装、配置与高级功能详解
linux·http·apache
止语Lab3 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活3 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困3 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn3 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
dkbnull3 小时前
Spring Boot请求处理组件对比详解
java·spring boot
用户298698530143 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
不能只会打代码3 小时前
Day 011 — Spring 全家桶深度拆解
spring boot·mybatis·spring aop·spring mvc·spring ioc
用户77283104908403 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金3 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端