当前位置: 首页 > news >正文

处理HTTP请求体:精通`@RequestBody`、`@RequestHeader`与`@CookieValue`

摘要: 在上一章中,我们精通了如何从URL中提取信息,但这通常只用于定位资源或传递简单参数。当客户端需要向服务器发送复杂的数据结构(如创建一个新用户的完整信息)时,HTTP请求体(Request Body)便成为了主角。本章,我们将深入学习处理HTTP请求中“内容”部分的三大关键注解:@RequestBody@RequestHeader@CookieValue。通过掌握它们,你将能够轻松处理POST、PUT等请求中携带的JSON数据,读取请求头信息,并与客户端的Cookie进行交互,从而构建功能完备的Web API。


引言:超越URL的交互

在第13章,我们学会了如何像一个侦探一样,从URL的各个角落(路径、查询参数、矩阵变量)中搜集线索。这对于GET请求来说通常已经足够。但Web世界远不止于此。当我们需要创建(POST)、更新(PUT)或删除(DELETE)资源时,往往需要传递更丰富、更结构化的信息。这些信息,正是存在HTTP请求的“包裹”——**请求体(Request Body)**中。

想象一下,注册一个新用户需要填写用户名、密码、邮箱、年龄等十几个字段,如果把这些都塞进URL里,那将是一场灾难。正确的做法是将这些数据打包成一个JSON对象,放在请求体中发送。

本章,我们将聚焦于如何打开并处理这个“数据包裹”,以及如何读取附在包裹上的“标签”(请求头)和“特殊凭证”(Cookie)。

一、@RequestBody:接收和转换请求体数据

@RequestBody是处理现代API(尤其是RESTful API)时最重要、最常用的注解之一。它告诉Spring Boot将HTTP请求体中的内容(通常是JSON或XML格式)反序列化成一个Java对象。

1. 场景

客户端希望创建一个新用户,它会发送一个POST请求到/users,请求体中包含如下JSON数据:

{"username": "CoderBO","email": "coderbo@example.com","age": 28
}

我们需要在后端接收这个JSON,并将其转换为一个User对象进行处理。

2. 创建数据传输对象 (DTO)

为了承载请求体中的数据,最佳实践是创建一个专门的DTO(Data Transfer Object)。

com.example.myfirstapp下创建一个dto包,并新建UserCreationDTO.java

package com.example.myfirstapp.dto;// DTO不需要是实体类,它只是一个简单的数据载体
public class UserCreationDTO {private String username;private String email;private Integer age;// 为了让Spring的Jackson库能正确反序列化,// 必须提供 public 的 getter 和 setter 方法。// 一个无参构造函数也是推荐的,尽管不总是必需。public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "UserCreationDTO{" +"username='" + username + '\'' +", email='" + email + '\'' +", age=" + age +'}';}
}

3. 代码实战

UserController中,添加一个处理POST请求的方法:

import com.example.myfirstapp.dto.UserCreationDTO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
// ... 其他import@RestController
@RequestMapping("/users")
public class UserController {// ... 其他GET方法 .../*** 使用 @RequestBody 接收POST请求的JSON数据体* @param userDTO Spring会自动将请求体中的JSON映射到这个DTO对象的字段上* @return 返回一个表示操作成功的Map*/@PostMappingpublic Map<String, Object> createUser(@RequestBody UserCreationDTO userDTO) {// 在实际应用中,这里会调用Service层将DTO转换为实体并存入数据库System.out.println("Received user to create: " + userDTO);return Map.of("success", true,"message", "User created successfully","createdUser", userDTO );}
}

代码解读:

  • @PostMapping: 这是一个快捷注解,等同于@RequestMapping(method = RequestMethod.POST)。它将此方法绑定到对/users的POST请求。
  • @RequestBody UserCreationDTO userDTO: 这是核心。@RequestBody指示Spring查看HTTP请求的内容部分,并使用内置的HttpMessageConverter(对于JSON,默认是Jackson)将其转换为UserCreationDTO类型的Java对象。

4. 效果演示

这次我们必须使用能发送POST请求并附带请求体的工具,如curl或Postman。

使用curl:

curl -X POST http://localhost:8080/users \
-H "Content-Type: application/json" \
-d '{"username": "CoderBO","email": "coderbo@example.com","age": 28
}'

响应:

{"success": true,"message": "User created successfully","createdUser": {"username": "CoderBO","email": "coderbo@example.com","age": 28}
}

同时,你会在应用的控制台看到打印的日志。

二、@RequestHeader:读取请求头信息

HTTP请求头包含了关于请求的元数据,如客户端类型(User-Agent)、期望的响应格式(Accept)等。@RequestHeader可以方便地将这些值注入到方法参数中。

1. 场景

我们需要记录下是哪个客户端(浏览器、移动App、爬虫)发起了请求,或者根据特定的头信息(如X-Client-Version)执行不同的逻辑。

2. 代码实战

UserController中添加一个新方法:

import org.springframework.web.bind.annotation.RequestHeader;
// ... 其他import@RestController
@RequestMapping("/users")
public class UserController {// ... 其他方法 ...@GetMapping("/headers")public Map<String, String> getHeaders(@RequestHeader("User-Agent") String userAgent,@RequestHeader(value = "Accept-Language", defaultValue = "en-US") String acceptLanguage,@RequestHeader(value = "X-Custom-Header", required = false) String customHeader) {return Map.of("User-Agent", userAgent,"Accept-Language", acceptLanguage,"X-Custom-Header", customHeader != null ? customHeader : "not present");}
}

代码解读:

  • @RequestHeader的用法与@RequestParam非常相似,同样支持valuedefaultValuerequired属性。
  • @RequestHeader("User-Agent"): 直接获取名为User-Agent的头信息。
  • @RequestHeader(value = "X-Custom-Header", required = false): 获取一个自定义的、非必需的头信息。

3. 效果演示

使用curl发送一个带自定义头的请求:

curl http://localhost:8080/users/headers \
-H "Accept-Language: zh-CN" \
-H "X-Custom-Header: my-app-v1.2.3"

响应:

{"User-Agent": "curl/7.79.1","Accept-Language": "zh-CN","X-Custom-Header": "my-app-v1.2.3"
}

三、@CookieValue:获取Cookie值

Cookie是服务器发送到用户浏览器并保存在本地的一小块数据。它会在浏览器下次向同一服务器再次发起请求时被携带上,用于维持用户登录状态、跟踪用户行为等。@CookieValue可以轻松读取这些Cookie。

1. 场景

假设用户登录后,服务器在客户端种下了一个名为session-id的Cookie。后续的请求都需要携带这个Cookie,我们需要在后端读取它以识别用户。

2. 代码实战

import org.springframework.web.bind.annotation.CookieValue;
// ... 其他import@RestController
@RequestMapping("/users")
public class UserController {// ... 其他方法 ...@GetMapping("/cookies")public Map<String, String> getCookies(@CookieValue("JSESSIONID") String sessionId, // 通常由Web容器自动生成@CookieValue(value = "my-custom-cookie", required = false, defaultValue = "default-value") String customCookie) {return Map.of("JSESSIONID", sessionId,"my-custom-cookie", customCookie);}
}

代码解读:

  • @CookieValue的用法也和@RequestParam高度一致,支持valuedefaultValuerequired

3. 效果演示

使用curl模拟一个带Cookie的请求:

curl http://localhost:8080/users/cookies \
--cookie "JSESSIONID=ABCDEFG12345; my-custom-cookie=hello-world"

响应:

{"JSESSIONID": "ABCDEFG12345","my-custom-cookie": "hello-world"
}

四、总结

本章我们掌握了处理HTTP请求“内容”部分的三个核心注解,它们与上一章的URL参数注解共同构成了Spring MVC参数绑定的基石。

核心功能
Spring MVC注解
HTTP请求结构
处理
处理
处理
反序列化JSON/XML
到Java对象(DTO)
用于POST/PUT
@RequestBody
读取请求元数据
如User-Agent, Accept
@RequestHeader
读取客户端Cookie
用于会话管理
@CookieValue
@PathVariable, @RequestParam, @MatrixVariable
@RequestHeader, @CookieValue
@RequestBody
请求头 (Headers)
请求行 (Method, URL)
请求体 (Body)

通过这两章的学习,你已经具备了处理绝大部分Web请求参数的能力,无论是来自URL还是请求本身。

预告:Spring MVC的参数绑定功能非常强大,但如果遇到一些特殊的、非标准的请求格式,比如"42,user,active"这样的字符串,我们希望直接将其绑定到一个自定义对象中,该怎么做呢?下一章,我们将学习一个更高级的技巧:实现自定义参数绑定:将复杂请求灵活映射至Java对象,让你的参数处理能力更上一层楼。

http://www.dtcms.com/a/296852.html

相关文章:

  • 计算机视觉技术剖析:轮廓检测、模板匹配及特征点匹配
  • SpringBoot框架简介
  • Windows本地部署DeepSeek
  • git更新内核补丁完整指南
  • 【C++】使用中值滤波算法过滤数据样本中的尖刺噪声
  • Java 并发容器:ConcurrentHashMap 笔记(JDK 1.8)
  • 01_FOC学习之先让电机转动起来
  • 双紫擒龙紫紫红黄安装使用攻略,2025通达信指标源码,擒龙追踪源码公式学习
  • 爬虫基础概念
  • 浏览器访问[http://www.taobao.com](http://www.taobao.com/),经历了怎样的过程。
  • DNS域名解析过程
  • 通达OA二次开发
  • Impact rating 影响等级定义(学习笔记)
  • YOLOv8 剪枝模型加载踩坑记:解决 YAML 覆盖剪枝结构的问题
  • 【JAVA】使用vosk实现windows实时语音转文字,解放双手
  • vs2019 创建MFC ActiveX的详细步骤
  • JS事件基础
  • ESP-NOW无线通信协议:物联网设备间的高效对话方式
  • 前端基础知识Vue系列 - 24(axios的原理)
  • Linux(centos7)安装 docker + ollama+ deepseek-r1:7b + Open WebUI(内含一键安装脚本)
  • Windows下使用UIAutomation技术遍历桌面窗口和指定窗口内容的AutomationWalker.exe的C#源代码
  • QT元对象系统-(1)静态属性和动态属性
  • Jenkins配置与应用指南
  • 外贸公司经营步骤
  • AI赋能软件工程让测试左移更加可实施
  • 《C++》面向对象编程--类(下)
  • IPv6网络优化
  • ANSYS Fluent 管内流动仿真
  • 如何恢复mysql,避免被研发删库跑路
  • Python(09)正则表达式