Required request body is missing with ContentCachingRequestWrapper

博客作者在使用Spring MVC时遇到一个问题,即在使用ContentCachingRequestWrapper包装request以实现重复读取请求体后,@RequestBody注解仍无法正常工作,导致HttpMessageNotReadableException。问题在于ContentCachingRequestWrapper未覆盖getInputStream方法。作者通过查阅资料并尝试自定义HttpServletRequestWrapper来重写getInputStream方法,最终解决了这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我有个拦截器,在进入我的controller之前,我读取了request的body,原始的 request是不可重复读的,于是决定使用ContentCachingRequestWrapper包装一下,但是在使用@RequestBody接收参数的时候后端报错,日志如下:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

前端响应为

{
    "timestamp": "2021-07-21T11:53:55.637+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Required request body is missing: public java.lang.String com.example.demo.controller.HelloController.post(com.example.demo.model.PostVO,javax.servlet.http.HttpServletRequest)",
    "path": "/post"
}

这不对呀,我都已经包装成可重复读的了呀,google一顿,StackOverflow没找到解决方案,但是
这里找到了说明,说是ContentCachingRequestWrapper没有重载HttpServletRequestWrapper的getInputStream方法,当用RequestBody接收参数的时候会使用这个方法,于是不再使用ContentCachingRequestWrapper,自己重写了HttpServletRequestWrapper

在处理 HTTP 请求时,出现 `POST Required request body is missing` 错误通常表明服务器期望接收到一个包含数据的请求体(request body),但实际上并未接收到有效的内容。这种情况常见于 RESTful API 的开发中,尤其是在使用如 Spring Boot 等框架进行后端开发时。 ### 常见原因分析 1. **客户端未发送请求体** 客户端在发起 POST 请求时,必须确保请求体中包含必要的数据。如果请求体为空或格式不正确,服务器将无法解析并返回错误信息。例如,在使用 `application/json` 内容类型时,若未提供 JSON 数据,则会触发此错误[^3]。 2. **请求头中的 Content-Type 设置错误** 如果客户端没有正确设置 `Content-Type` 请求头,或者设置的类型与实际发送的数据格式不符,服务器可能无法识别请求体的内容,从而导致解析失败。 3. **Spring MVC 中的 @RequestBody 注解问题** 在 Spring MVC 中,当方法参数使用了 `@RequestBody` 注解时,框架会尝试将 HTTP 请求体转换为 Java 对象。如果请求体为空或格式不符合预期(如 JSON 格式错误),则会抛出异常并返回 400 错误码。例如,Spring 3.2.2 版本中可能会看到如下堆栈跟踪: ``` at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948) ``` 这表明请求处理过程中未能成功解析请求体。 4. **前端或 API 测试工具配置不当** 使用 Postman、curl 或其他测试工具时,如果没有正确构造请求体或选择了错误的请求方法(如 GET 而非 POST),也会导致此类问题。 --- ### 解决方案 #### 1. 检查客户端请求是否包含有效请求体 确保客户端发送的 POST 请求中确实包含了请求体,并且内容符合服务器预期的格式。例如,如果是 JSON 格式,应确保结构正确: ```json { "username": "test", "password": "123456" } ``` #### 2. 验证请求头中的 Content-Type 确认请求头中设置了正确的 `Content-Type`,例如: ``` Content-Type: application/json ``` 如果不设置该字段或设置为其他值(如 `text/plain`),Spring 可能不会尝试解析 JSON 数据。 #### 3. 使用 @Valid 注解进行参数校验 在 Spring 控制器中,可以结合 `@Valid` 注解对请求体进行验证,防止空值或格式错误的情况: ```java @PostMapping("/users") public ResponseEntity<?> createUser(@Valid @RequestBody User user, BindingResult result) { if (result.hasErrors()) { return new ResponseEntity<>(result.getAllErrors(), HttpStatus.BAD_REQUEST); } // 处理业务逻辑 } ``` #### 4. 异常处理器统一处理错误 通过实现 `@ControllerAdvice` 或 `@ExceptionHandler`,可以捕获并处理 `HttpMessageNotReadableException` 异常,该异常通常由空请求体或格式错误引发: ```java @ControllerAdvice public class RequestBodyExceptionAdvice { @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity<String> handleEmptyRequestBody() { return new ResponseEntity<>("Request body is missing or malformed", HttpStatus.BAD_REQUEST); } } ``` #### 5. 使用默认值或可选字段 如果某些字段允许为空,可以在 DTO 类中使用 `@JsonInclude(Include.NON_NULL)` 注解来忽略空字段,避免因个别字段缺失而报错: ```java @Data @JsonInclude(JsonInclude.Include.NON_NULL) public class UserDTO { private String name; private String email; } ``` --- ### 总结 `POST Required request body is missing` 是一个常见的 HTTP 错误,主要涉及请求体缺失、格式错误或框架配置问题。通过检查客户端请求、设置正确的 `Content-Type`、合理使用注解进行参数校验和异常处理,可以有效解决这一问题。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值