网络
网络
HTTP 不同的 Content-Type(consumes)
Content-Type 是 HTTP 请求头中用于指定请求体的媒体类型(MIME 类型)。在 Spring 中,通过 consumes 属性来指定接口接受的媒体类型。
1. application/json
说明:最常用的 JSON 格式,用于传输结构化数据。
特点:
- 可读性好,易于调试
- 支持嵌套对象和数组
- 广泛支持,前后端通用
使用示例:
@PostMapping(value = "/users", consumes = "application/json")
public Result createUser(@RequestBody UserDTO userDTO) {
// 处理 JSON 数据
return userService.createUser(userDTO);
}
// 前端请求
// Content-Type: application/json
// Body: {"userName":"张三","email":"[email protected]"}2. application/x-www-form-urlencoded
说明:表单提交的默认格式,数据以键值对形式编码。
特点:
- 浏览器原生支持
- 数据以
key=value&key2=value2格式编码 - URL 编码,特殊字符会被转义
使用示例:
@PostMapping(value = "/login", consumes = "application/x-www-form-urlencoded")
public Result login(@RequestParam String username, @RequestParam String password) {
// 处理表单数据
return authService.login(username, password);
}
// 前端请求
// Content-Type: application/x-www-form-urlencoded
// Body: username=zhangsan&password=1234563. application/xml
说明:XML 格式,用于传输结构化数据。
特点:
- 可读性好,但比 JSON 冗长
- 支持命名空间和 Schema 验证
- 常用于 SOAP 服务和传统系统集成
使用示例:
@PostMapping(value = "/users", consumes = "application/xml")
public Result createUser(@RequestBody UserDTO userDTO) {
// 处理 XML 数据
return userService.createUser(userDTO);
}
// 请求示例
// Content-Type: application/xml
// Body: <user><userName>张三</userName><email>[email protected]</email></user>4. application/x-protobuf
说明:Google Protocol Buffers 二进制序列化格式。
特点:
- 体积小,性能高
- 跨语言支持
- 需要定义 .proto 文件
- 常用于微服务间通信
使用示例:
@PostMapping(value = "/users", consumes = "application/x-protobuf")
public ResponseEntity<UserProto.User> createUser(@RequestBody UserProto.User user) {
// 处理 Protobuf 数据
return ResponseEntity.ok(userService.createUser(user));
}5. application/x-msgpack
说明:MessagePack 二进制序列化格式。
特点:
- 比 JSON 更紧凑
- 序列化/反序列化速度快
- 支持多种数据类型
使用示例:
@PostMapping(value = "/users", consumes = "application/x-msgpack")
public Result createUser(@RequestBody UserDTO userDTO) {
// 处理 MessagePack 数据
return userService.createUser(userDTO);
}6. application/x-thrift
说明:Apache Thrift 二进制序列化格式。
特点:
- 跨语言 RPC 框架
- 性能高,体积小
- 需要定义 .thrift 文件
使用示例:
@PostMapping(value = "/users", consumes = "application/x-thrift")
public Result createUser(@RequestBody UserThrift user) {
// 处理 Thrift 数据
return userService.createUser(user);
}7. application/x-yaml
说明:YAML 格式,人类可读的数据序列化格式。
特点:
- 可读性好
- 支持注释
- 常用于配置文件
使用示例:
@PostMapping(value = "/config", consumes = "application/x-yaml")
public Result updateConfig(@RequestBody ConfigDTO config) {
// 处理 YAML 数据
return configService.updateConfig(config);
}8. application/x-toml
说明:TOML(Tom's Obvious Minimal Language)格式。
特点:
- 可读性好
- 常用于配置文件
- 支持嵌套结构
9. application/x-ini
说明:INI 配置文件格式。
特点:
- 简单的键值对格式
- 常用于 Windows 配置文件
10. application/x-properties
说明:Java Properties 文件格式。
特点:
- 键值对格式
- 常用于 Java 配置文件
11. application/x-env
说明:环境变量格式。
特点:
- 简单的键值对格式
- 常用于环境配置
Content-Type 对比
| 类型 | 格式 | 体积 | 性能 | 可读性 | 使用场景 |
|---|---|---|---|---|---|
| application/json | 文本 | 中 | 中 | 高 | 前后端交互、API |
| application/x-www-form-urlencoded | 文本 | 中 | 中 | 中 | 表单提交 |
| application/xml | 文本 | 大 | 低 | 高 | SOAP、传统系统 |
| application/x-protobuf | 二进制 | 小 | 高 | 低 | 微服务通信 |
| application/x-msgpack | 二进制 | 小 | 高 | 低 | 高性能场景 |
| application/x-thrift | 二进制 | 小 | 高 | 低 | RPC 调用 |
HTTP 请求头的作用
HTTP 请求头(Request Headers)用于传递请求的元数据信息,帮助服务器理解请求的上下文和处理方式。
常用请求头
1. Content-Type
作用:指定请求体的媒体类型。
// 指定请求体为 JSON
Content-Type: application/json
// 指定请求体为表单数据
Content-Type: application/x-www-form-urlencoded
// 指定请求体为 XML
Content-Type: application/xml2. Accept
作用:指定客户端能够接受的响应媒体类型。
// 接受 JSON 响应
Accept: application/json
// 接受多种类型,按优先级排序
Accept: application/json, application/xml, text/plain3. Authorization
作用:用于身份认证,通常包含 token 或凭证。
// Bearer Token
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// Basic Auth
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=4. User-Agent
作用:标识客户端类型和版本。
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.365. Referer
作用:标识请求来源页面。
Referer: https://www.example.com/page16. Origin
作用:标识请求的源(用于 CORS)。
Origin: https://www.example.com7. Cookie
作用:传递客户端存储的 Cookie。
Cookie: sessionId=abc123; userId=4568. X-Requested-With
作用:标识是否为 AJAX 请求。
X-Requested-With: XMLHttpRequest9. X-Forwarded-For
作用:标识客户端的真实 IP(经过代理时)。
X-Forwarded-For: 192.168.1.1, 10.0.0.110. Content-Length
作用:指定请求体的字节长度。
Content-Length: 1024Spring 相关注解
1. @RequestBody
作用:将请求体绑定到方法参数,通常用于 POST/PUT 请求。
特点:
- 自动反序列化请求体
- 支持 JSON、XML 等格式
- 需要配置消息转换器
使用示例:
@PostMapping("/users")
public Result createUser(@RequestBody UserDTO userDTO) {
// userDTO 自动从请求体反序列化
return userService.createUser(userDTO);
}
// 支持验证注解
@PostMapping("/users")
public Result createUser(@Valid @RequestBody UserCreateDTO dto) {
// 自动进行参数验证
return userService.createUser(dto);
}
// 指定 Content-Type
@PostMapping(value = "/users", consumes = "application/json")
public Result createUser(@RequestBody UserDTO userDTO) {
return userService.createUser(userDTO);
}2. @RequestParam
作用:绑定请求参数(URL 参数或表单数据)到方法参数。
特点:
- 用于 URL 查询参数或表单数据
- 可以设置默认值和是否必需
- 支持多个同名参数(使用 List)
使用示例:
// 基本使用
@GetMapping("/users")
public Result getUsers(@RequestParam String name) {
// URL: /users?name=张三
return userService.findByName(name);
}
// 设置默认值
@GetMapping("/users")
public Result getUsers(@RequestParam(defaultValue = "1") Integer page) {
// URL: /users?page=2 或 /users(使用默认值1)
return userService.getUsers(page);
}
// 设置是否必需
@GetMapping("/users")
public Result getUsers(@RequestParam(required = false) String name) {
// name 参数可选
if (name != null) {
return userService.findByName(name);
}
return userService.getAllUsers();
}
// 多个同名参数
@GetMapping("/users")
public Result getUsers(@RequestParam List<String> ids) {
// URL: /users?ids=1&ids=2&ids=3
return userService.findByIds(ids);
}
// 指定参数名
@GetMapping("/users")
public Result getUsers(@RequestParam("user_name") String userName) {
// URL: /users?user_name=张三
return userService.findByName(userName);
}3. @RequestHeader
作用:绑定请求头到方法参数。
特点:
- 获取 HTTP 请求头信息
- 可以设置默认值和是否必需
- 支持多个同名请求头
使用示例:
// 基本使用
@GetMapping("/users")
public Result getUsers(@RequestHeader("Authorization") String token) {
// 获取 Authorization 请求头
return userService.getUsers(token);
}
// 设置默认值
@GetMapping("/users")
public Result getUsers(@RequestHeader(value = "User-Agent", defaultValue = "Unknown") String userAgent) {
// 获取 User-Agent,如果没有则使用默认值
return userService.getUsers(userAgent);
}
// 设置是否必需
@GetMapping("/users")
public Result getUsers(@RequestHeader(required = false) String token) {
// token 请求头可选
if (token != null) {
return userService.getUsers(token);
}
return userService.getAllUsers();
}
// 获取多个同名请求头
@GetMapping("/users")
public Result getUsers(@RequestHeader List<String> customHeaders) {
// 获取所有同名请求头
return userService.getUsers(customHeaders);
}4. @RequestAttribute
作用:从请求属性(Request Attributes)中获取值,通常用于过滤器或拦截器设置的值。
特点:
- 获取请求作用域内的属性
- 通常由过滤器或拦截器设置
- 在同一请求内共享
使用示例:
// 在拦截器中设置
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 设置请求属性
request.setAttribute("userId", getUserIdFromToken(request));
return true;
}
}
// 在 Controller 中获取
@GetMapping("/users/me")
public Result getCurrentUser(@RequestAttribute("userId") Long userId) {
// 从请求属性中获取 userId
return userService.getUserById(userId);
}5. @RequestHeaderMap / @RequestHeaderMultiValueMap
说明:这两个注解实际上不存在,但可以通过 Map 或 MultiValueMap 类型配合 @RequestHeader 获取所有请求头。
使用示例:
// 获取所有请求头(Map)
@GetMapping("/users")
public Result getUsers(@RequestHeader Map<String, String> headers) {
// headers 包含所有请求头
String token = headers.get("Authorization");
return userService.getUsers(token);
}
// 获取所有请求头(MultiValueMap,支持同名请求头)
@GetMapping("/users")
public Result getUsers(@RequestHeader MultiValueMap<String, String> headers) {
// headers 包含所有请求头,支持同名请求头的多个值
List<String> customHeaders = headers.get("X-Custom-Header");
return userService.getUsers(customHeaders);
}6. @PathVariable
作用:绑定 URL 路径变量到方法参数。
使用示例:
@GetMapping("/users/{id}")
public Result getUser(@PathVariable Long id) {
// URL: /users/123,id = 123
return userService.getUserById(id);
}
// 指定路径变量名
@GetMapping("/users/{userId}/orders/{orderId}")
public Result getOrder(
@PathVariable("userId") Long userId,
@PathVariable("orderId") Long orderId) {
return orderService.getOrder(userId, orderId);
}7. @ModelAttribute
作用:绑定请求参数到模型对象(通常用于表单提交)。
使用示例:
@PostMapping("/users")
public Result createUser(@ModelAttribute UserDTO userDTO) {
// 自动绑定表单数据到 userDTO
return userService.createUser(userDTO);
}8. @RequestPart
作用:绑定请求体中的部分数据到方法参数,通常用于文件上传。 特点:
- 用于绑定请求体中的部分数据
- 通常用于文件上传
- 支持 multipart/form-data 格式 使用示例:
@PostMapping(value = "/upload", consumes = "multipart/form-data")
public Result uploadFile(@RequestPart("file") MultipartFile file) {
return fileService.uploadFile(file);
}完整示例
@RestController
@RequestMapping("/api/users")
@Slf4j
public class UserController {
/**
* 创建用户 - JSON 格式
*/
@PostMapping(value = "/json", consumes = "application/json")
public Result createUserJson(@RequestBody @Valid UserCreateDTO dto) {
return userService.createUser(dto);
}
/**
* 创建用户 - 表单格式
*/
@PostMapping(value = "/form", consumes = "application/x-www-form-urlencoded")
public Result createUserForm(
@RequestParam String userName,
@RequestParam String email,
@RequestParam String password) {
UserCreateDTO dto = UserCreateDTO.builder()
.userName(userName)
.email(email)
.password(password)
.build();
return userService.createUser(dto);
}
/**
* 查询用户 - 带请求头
*/
@GetMapping("/{id}")
public Result getUser(
@PathVariable Long id,
@RequestHeader("Authorization") String token,
@RequestHeader(value = "X-Request-Id", required = false) String requestId) {
// 验证 token
authService.validateToken(token);
// 记录请求 ID(用于追踪)
if (requestId != null) {
log.info("Request ID: {}", requestId);
}
return userService.getUserById(id);
}
/**
* 获取所有请求头
*/
@GetMapping("/headers")
public Result getHeaders(@RequestHeader Map<String, String> headers) {
return Result.success(headers);
}
/**
* 使用请求属性(由拦截器设置)
*/
@GetMapping("/me")
public Result getCurrentUser(@RequestAttribute("userId") Long userId) {
return userService.getUserById(userId);
}
}最佳实践
选择合适的 Content-Type:
- 前后端交互:使用
application/json - 表单提交:使用
application/x-www-form-urlencoded - 微服务通信:考虑使用
application/x-protobuf提升性能
- 前后端交互:使用
参数验证:
- 使用
@Valid配合验证注解进行参数校验 - 设置
required = false处理可选参数
- 使用
请求头管理:
- 使用
@RequestHeader获取必要的请求头 - 设置默认值处理缺失的请求头
- 使用
错误处理:
- 处理 Content-Type 不匹配的情况
- 处理参数缺失或格式错误的情况
安全性:
- 验证 Authorization 请求头
- 注意 X-Forwarded-For 等请求头的安全性
