Java HttpClient POST请求发送空体问题(JDK11/17)
JDK 11/17 HttpClient POST请求体为空问题
问题现象
在JDK 11和JDK 17环境下,使用java.net.http.HttpClient发送携带"hello"内容的POST请求时,服务器端收到的请求体为空。具体特征:
- 代码执行无异常抛出
- 响应状态码返回202
- 请求头中
content-length字段显示为5,但服务器实际未接收到请求体内容 - 已在多种服务器实现及Postman模拟服务器上验证,代码运行于JUnit测试环境,使用JVM为OpenJDK 64-Bit Server VM Temurin-17.0.5+8
问题代码示例
val response = java.net.http.HttpClient.newHttpClient() .send( java.net.http.HttpRequest.newBuilder() .uri(URI.create("http://....")) .POST(java.net.http.HttpRequest.BodyPublishers.ofString("hello", StandardCharsets.UTF_8)) .build(), java.net.http.HttpResponse.BodyHandlers.ofString());
调试发现(2023-02-05更新)
调试JVM时观察到两个待发送缓冲区:
- 第一个缓冲区包含9个字符(推测为编码消息起始帧)
- 第二个缓冲区包含5个字符(对应"hello"的ASCII码:104、101、108、108、111)
但实际Body Publisher仅发送了前9个字符,未传输包含实际负载的5字符缓冲区。
解决方案建议
- 显式添加Content-Type请求头:
BodyPublishers.ofString默认不会自动设置Content-Type,部分服务器因缺少该头无法正确解析请求体,可添加:.header("Content-Type", "text/plain; charset=UTF-8") - 强制使用HTTP/1.1协议:部分HTTP/2的实现可能存在帧发送异常,尝试构建客户端时指定协议版本:
HttpClient client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) .build(); - 排除测试环境干扰:将代码移至独立main方法中运行,排查JUnit或测试拦截器是否修改了请求内容
- 升级JDK版本:该问题可能是特定版本的已知Bug,尝试升级到Temurin 17的最新版本(如17.0.10+及以上)
内容的提问来源于stack exchange,提问作者Jan Dolejsi
相关产品推荐
相关产品推荐

