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,让你的代码更健壮。根据场景选择即可!

相关推荐
后端小张13 分钟前
【JAVA进阶】Spring Boot 核心知识点之自动配置:原理与实战
java·开发语言·spring boot·后端·spring·spring cloud·自动配置
3***C7445 小时前
Spring Boot 整合 log4j2 日志配置教程
spring boot·单元测试·log4j
X***C8625 小时前
SpringBoot:几种常用的接口日期格式化方法
java·spring boot·后端
i***t9195 小时前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
8***84826 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
o***74176 小时前
基于SpringBoot的DeepSeek-demo 深度求索-demo 支持流式输出、历史记录
spring boot·后端·lua
9***J6286 小时前
Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
java·spring boot·后端
S***q1926 小时前
Rust在系统工具中的内存安全给代码上了三道保险锁。但正是这种“编译期的严苛”,换来了运行时的安心。比如这段代码:
开发语言·后端·rust
v***7946 小时前
Spring Boot 热部署
java·spring boot·后端
追逐时光者7 小时前
C#/.NET/.NET Core优秀项目和框架2025年11月简报
后端·.net