You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试HttpMessageNotReadableException?排查请求解析异常问题

分析HTTP请求问题与实用调试指南

嘿,我来帮你捋清楚这个问题!虽然你没贴出具体的DTO定义、控制器代码和httpie请求内容,但我先给你梳理最常见的请求错误坑点,再重点讲怎么调试这类问题——毕竟掌握调试方法比解决单个问题更重要。

一、先排查这些常见的请求问题

大概率你的请求踩了以下某一个坑:

  • Content-Type不匹配:比如你的控制器用@RequestBody接收JSON格式,但httpie默认发的是application/x-www-form-urlencoded表单格式。举个例子:如果要发JSON,httpie得用key:=value(冒号加等号)而不是key=value,或者显式加请求头Content-Type:application/json。反过来,如果控制器期望表单,你却发了JSON,也会报错。
  • 字段名/类型不匹配:DTO里是userName(驼峰),但请求里传的是username(全小写);或者DTO里是Integer类型的age,你却传了字符串"twenty",这种类型不匹配会直接导致参数绑定失败。
  • 必填字段缺失:如果DTO里的字段加了@NotNull/@NotEmpty这类校验注解,请求里没传这些字段,会触发参数校验报错。
  • 请求方法不对:比如控制器是@GetMapping,你却用httpie发了POST请求,直接返回405 Method Not Allowed。

二、核心调试方法:从外到内定位问题

这部分是关键,不管遇到什么请求错误,按这个流程走都能快速找到根源:

1. 先看报错响应,抓关键信息

别跳过报错内容!比如返回400 Bad Request时,响应体里通常会有明确的提示,比如:

JSON parse error: Cannot deserialize value of type java.lang.Integer from String "abc"; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException...

这种直接就告诉你是字段类型不匹配。如果是500错误,把完整的堆栈信息拉出来,找到你自己代码里的报错行,那就是问题点。

2. 用httpie的 verbose 模式看真实请求

发送请求时加-v参数,它会把完整的请求头、请求体都打印出来,比如:

http -v POST /api/user name:=张三 age:=25

通过这个输出你能确认:

  • 请求方法、URL是不是和控制器映射的一致
  • Content-Type是不是符合预期
  • 实际发送的请求体内容是什么,是不是和你想的一样(比如有没有漏字段、字段名写错)

3. 在控制器里加日志,确认请求是否到达

用日志打印接收的参数,比如Spring Boot里用@Slf4j注解:

@Slf4j
@RestController
public class UserController {
    @PostMapping("/api/user")
    public ResponseEntity<UserDto> createUser(@RequestBody UserDto userDto) {
        // 打印完整的DTO对象,看接收的参数对不对
        log.info("Received request DTO: {}", userDto);
        // 后续业务逻辑
        return ResponseEntity.ok(userDto);
    }
}

如果日志没输出,说明请求根本没到控制器——那问题可能出在路由不匹配、拦截器/过滤器拦截了,或者请求URL写错了。

4. 开启框架调试日志,看底层处理流程

如果是参数绑定、JSON解析这类框架层面的错误,开启Spring Boot的调试日志,在application.yml里加:

logging:
  level:
    org.springframework.web: DEBUG
    com.fasterxml.jackson: DEBUG

这样你能看到Spring MVC处理请求的完整流程:怎么匹配路由、怎么解析请求体、怎么把JSON转成DTO,哪一步抛出了异常,一目了然。

5. 单独测试DTO的序列化/反序列化

有时候问题出在DTO本身的注解上,比如Jackson的@JsonProperty名字写错了,或者私有字段没加setter,或者自定义序列化器有问题。可以写个简单的单元测试验证:

@Test
void testDtoJsonConversion() {
    String testJson = "{\"userName\":\"张三\",\"age\":25}";
    ObjectMapper mapper = new ObjectMapper();
    try {
        // 把JSON转成DTO,看是否报错
        UserDto dto = mapper.readValue(testJson, UserDto.class);
        System.out.println("Parsed DTO: " + dto);
        // 再把DTO转成JSON,看是否和原JSON一致
        String serializedJson = mapper.writeValueAsString(dto);
        System.out.println("Serialized JSON: " + serializedJson);
    } catch (JsonProcessingException e) {
        e.printStackTrace(); // 这里的异常就是问题根源
    }
}

这样能快速排除是不是DTO本身的问题,和控制器无关。

6. 排查拦截器/过滤器的影响

如果请求没到控制器,检查一下项目里的拦截器、过滤器,比如登录验证拦截器、跨域过滤器。可以暂时禁用这些组件,或者在拦截器里加日志,看请求是不是被拦截了。


内容的提问来源于stack exchange,提问作者shredding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:09:29