React调用Spring PATCH接口更新时提示RequestBody缺失如何解决
问题原因
你的猜测是对的,核心原因就是axios传递普通字符串时默认不会按JSON格式发送请求,导致Spring无法解析到@RequestBody标注的参数,触发请求体缺失报错:
- 当
axios.patch的第二个参数传入原始类型(字符串、数字等)时,axios默认会将Content-Type设为text/plain,直接把字符串作为请求体发送 - 而Spring接口的String参数加了
@RequestBody注解,默认需要application/json类型的请求体,纯文本格式的请求体无法被JSON消息转换器解析,就会抛出请求体缺失异常 - Postman测试时你应该是选择了raw/JSON格式传入字符串,Postman会自动给字符串加双引号、设置Content-Type为
application/json,所以能正常调用
修复方案
方案1:前端修改(推荐,无需改动后端接口)
调整OrderService的请求代码,手动将字符串序列化为JSON格式,并指定请求头:
async updateDeliveryStatus(orderId,deliveryStatus){ return await axios.patch( BASE_URL+"/"+orderId, JSON.stringify(deliveryStatus), // 序列化为JSON格式字符串,相当于给纯字符串套上双引号 {headers: {'Content-Type': 'application/json'}} // 显式指定请求格式为JSON ) }
另外可以删掉UpdateOrder组件handleChange里的冗余代码,这行代码不影响功能但完全无用:
// 删掉下面这行,deliveryStatus是字符串无需展开,且后续setState也没有用到这个变量 const deliveryStatus = { ...this.state.deliveryStatus };
方案2:后端修改(如果不想改前端请求逻辑)
给Controller层的updateDeliveryStatus方法的String参数去掉@RequestBody注解,改为@RequestParam,然后前端将deliveryStatus放在请求参数里传递即可:
// Controller层调整示例(业务层代码无需改动) @PatchMapping("/{orderId}") public OrderDetails updateDeliveryStatus(@PathVariable int orderId, @RequestParam String deliveryStatus) { return orderDetailsService.updateDeliveryStatus(orderId, deliveryStatus); }
对应的前端请求调整为:
async updateDeliveryStatus(orderId,deliveryStatus){ return await axios.patch(BASE_URL+"/"+orderId, null, { params: { deliveryStatus: deliveryStatus } }) }
内容的提问来源于stack exchange,提问作者Sourav
相关产品推荐
相关产品推荐

