Spring @RequestBody注解详解与实践
@RequestBody
是 Spring MVC 中处理 HTTP 请求体的核心注解,用于将请求体(如 JSON、XML)中的数据绑定到 Java 对象。它是构建 RESTful API 和现代 Web 服务的基石,特别适用于前后端分离架构。
核心作用
- 数据绑定:将 HTTP 请求体内容转换为 Java 对象
- 内容协商:根据 Content-Type 自动选择消息转换器
- 类型转换:处理复杂嵌套对象和集合类型
基础用法
@RestController
@RequestMapping("/users")
public class UserController {// 将 JSON 请求体转换为 User 对象@PostMappingpublic ResponseEntity<User> createUser(@RequestBody User user) {User savedUser = userService.save(user);return ResponseEntity.ok(savedUser);}
}
请求示例:
POST /users HTTP/1.1
Content-Type: application/json{"name": "张三","email": "zhangsan@example.com","age": 28
}
工作原理
关键特性
1. 支持多种数据格式
Content-Type | 转换器 | 依赖库 |
---|---|---|
application/json | MappingJackson2HttpMessageConverter | Jackson (默认包含) |
application/xml | Jaxb2RootElementHttpMessageConverter | JAXB API (需 JDK 或依赖) |
text/xml | 同上 | 同上 |
application/x-www-form-urlencoded | FormHttpMessageConverter | Spring 核心 |
2. 支持复杂数据结构
// 嵌套对象
public class OrderRequest {@RequestBodyprivate User user;private List<OrderItem> items;
}// 集合类型
@PostMapping("/batch")
public void createUsers(@RequestBody List<User> users) {userService.batchCreate(users);
}
3. 验证支持
配合 @Valid
实现自动验证:
@PostMapping
public ResponseEntity<?> createUser(@Valid @RequestBody UserDto userDto, // 自动触发验证BindingResult result) {if (result.hasErrors()) {// 处理验证错误}// ...
}
最佳实践
1. 使用 DTO 而非实体类
// 请求专用 DTO
public class UserCreateDto {@NotBlankprivate String username;@Emailprivate String email;// 不包含敏感字段(如 password)
}// 响应专用 DTO
public class UserResponseDto {private Long id;private String displayName;
}
2. 全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {// 处理 JSON 解析错误@ExceptionHandler(HttpMessageNotReadableException.class)public ResponseEntity<ErrorResponse> handleJsonParseError() {return ResponseEntity.badRequest().body(new ErrorResponse("JSON_PARSE_ERROR", "请求体格式错误"));}
}
3. 自定义消息转换器
配置 XML 支持:
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
</dependency>
配置自定义转换器:
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 添加 Protobuf 转换器converters.add(new ProtobufHttpMessageConverter());}
}
常见问题解决
1. 400 Bad Request (解析失败)
原因:JSON 格式错误/字段类型不匹配
解决方案:
- 检查请求体 JSON 格式
- 确保 Java 字段类型匹配(如字符串不能赋给整数字段)
- 添加全局异常处理
2. 415 Unsupported Media Type
原因:缺少对应的消息转换器
解决方案:
// 明确指定消费类型
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public void create(@RequestBody User user)
3. 时区问题
现象:日期字段时区错误
解决方案:
public class UserDto {@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="Asia/Shanghai")private Date registrationDate;
}
4. 大文本处理
需求:接收大段文本
@PostMapping("/document")
public void uploadDocument(@RequestBody String markdownContent) {// 直接获取原始字符串
}
高级用法
1. 接收原始数据
@PostMapping("/raw")
public void handleRawBody(@RequestBody byte[] body) {// 处理二进制数据
}
2. 组合使用 @RequestPart
@PostMapping(value = "/profile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void uploadProfile(@RequestPart("meta") @Valid UserMetaDto meta,@RequestPart("avatar") MultipartFile avatar) {// 同时处理 JSON 和文件
}
3. 自定义反序列化
public class CustomUserDeserializer extends JsonDeserializer<User> {@Overridepublic User deserialize(JsonParser p, DeserializationContext ctx) {// 自定义解析逻辑}
}public class UserDto {@JsonDeserialize(using = CustomUserDeserializer.class)private User user;
}
与其他注解对比
注解 | 作用范围 | 数据类型 | 典型场景 |
---|---|---|---|
@RequestBody | 请求体 | 复杂对象/JSON | POST/PUT 请求 |
@RequestParam | URL 查询参数 | 简单类型 | GET 请求参数 |
@PathVariable | URL 路径片段 | 简单类型 | RESTful 资源路径 |
@ModelAttribute | 表单数据 | 简单/复合对象 | HTML 表单提交 |
性能优化建议
-
避免大对象:限制请求体大小(默认 2MB)
spring.servlet.multipart.max-request-size=10MB
-
启用压缩:配置服务器压缩
server.compression.enabled=true server.compression.mime-types=application/json
-
批处理设计:对大集合分页处理
@PostMapping("/batch") public void batchProcess(@RequestBody Page<User> userPage)
-
监控日志:记录大请求体
@Around("@annotation(requestBodyMethod)") public Object logRequestBody(ProceedingJoinPoint pjp) {// 记录请求体大小 }
总结
@RequestBody
是现代 Spring 应用的核心组件:
- ✅ 核心价值:实现请求体到 Java 对象的无缝转换
- ✅ 适用场景:RESTful API、微服务通信、前后端分离架构
- ✅ 最佳搭档:Jackson 库 + DTO 模式 + 验证机制
- ❌ 不适用场景:文件上传(用
MultipartFile
)、表单提交(用@ModelAttribute
)
设计原则:始终通过 DTO 控制接口输入,避免直接暴露实体类。结合 Swagger 文档和严格验证,可构建出健壮的 API 接口。