Spring Boot调用Open API遭遇400 Bad Request(Unreadable message)错误
问题排查与修复方案
1. API密钥配置错误
代码中设置API-Key时直接写死了字符串"apiKey",没有使用注入的apiKey变量:
// 错误写法 httpHeaders.set("API-Key", "apiKey"); // 正确写法 httpHeaders.set("API-Key", apiKey);
2. HttpEntity构造错误(请求体与请求头混淆)
当前代码把HttpHeaders当作HttpEntity的请求体参数传入,导致API收到的请求体是请求头的字符串表示,完全不符合接口解析要求,这是触发"Unreadable message"错误的核心原因:
// 错误写法:将headers作为body传入 HttpEntity<String> entity = new HttpEntity<>(httpHeaders); // 正确写法:区分请求体与请求头,若Postman有请求体则传入对应内容,无请求体则传null HttpEntity<String> entity = new HttpEntity<>(requestBodyJson, httpHeaders); // 无请求体时的写法 HttpEntity<String> entity = new HttpEntity<>(null, httpHeaders);
3. 不应该注入HttpHeaders
HttpHeaders是有状态对象,注入的单例实例会在多次调用方法时导致请求头被污染,应该在方法内部创建新实例:
// 移除类上的@Autowired注解 // @Autowired // private HttpHeaders httpHeaders; // 在方法内创建新的请求头对象 HttpHeaders httpHeaders = new HttpHeaders();
4. 变量名不一致(编译错误)
代码中定义了FlightResponse ApiResponse,但后续使用的是未定义的airFranceApiResponse,变量名不匹配会导致编译失败:
// 错误写法 FlightResponse ApiResponse = responseEntity.getBody(); double totalPrice = airFranceApiResponse.getDestinationCities()... // 正确写法 FlightResponse airFranceApiResponse = responseEntity.getBody(); double totalPrice = airFranceApiResponse.getDestinationCities()...
5. 缺失请求体(关键差异点)
Postman能正常请求说明必然携带了符合要求的请求体(JSON格式),但当前代码完全没有设置请求体内容。需要将Postman中的请求体转换成字符串或对应Java对象传入HttpEntity:
// 示例1:直接传入JSON字符串 String requestBody = "{\"param1\":\"value1\",\"param2\":\"value2\"}"; HttpEntity<String> entity = new HttpEntity<>(requestBody, httpHeaders); // 示例2:用Java对象转JSON(需确保RestTemplate配置了JSON消息转换器) FlightRequest request = new FlightRequest(); // 填充request的参数 HttpEntity<FlightRequest> entity = new HttpEntity<>(request, httpHeaders);
额外建议
- 开启RestTemplate的请求日志,打印完整的请求头、请求体内容,和Postman的请求做逐字段对比,快速定位差异。
- 确认
Content-Type与请求体格式匹配,若使用application/hal+json,需保证请求体符合HAL规范的JSON结构。
内容的提问来源于stack exchange,提问作者beyz
相关产品推荐
相关产品推荐

