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

使用java.net.HTTPClient请求返回400错误,Postman和RestTemplate正常

问题

在SpringBoot应用中,使用java.net.HTTPClient向指定URL发送JSON格式POST请求时,服务器返回400状态码,但用Postman或Spring RestTemplate发送相同请求却能得到预期响应。

我的代码

// some dummy url:
String url = "http://88.22.199.111:5000/detect";

JSONObject json1 = new JSONObject();
json1.put("From", "Sawan");
json1.put("to", "Mohan");
json1.put("message", "is API working?");
json1.put("check_list", 1);

HttpClient httpClient = HttpClient.newBuilder().build();

HttpRequest httpRequest = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json1.toString()))
        .build();

System.out.println(json1.toString());
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());

System.out.println(httpResponse.statusCode());
System.out.println(httpResponse.body());

控制台输出

{"check_list":1,"From":"Sawan","to":"Mohan","message":"is API working?"}
400
{"message": "The browser (or proxy) sent a request that this server could not understand."}

Postman对应的cURL命令

curl --location 'http://88.22.199.111:5000/detect' \
--header 'Content-Type: application/json' \
--data '{
    "From":"Sawan"
    ,"to":"Mohan"
    ,"message":"is API working?"
    ,"check_list":1
} '

预期响应

{
    "status": 200,
    "message": "Success",
    "timestamp": "2023-03-31 05:20:33.455868 +0000",
    "data": {
        "Message": "is API working?",
        "MessageTimeUTC": "Fri, 31 Mar 2023 05:20:33 GMT",
        "Message_By": "sawan",
        "Message_To": "mohan",
        "Message_Intended_For": "mohan",
        "Sentences": []
    }
}

由于实际应用中无法使用RestTemplate,需要解决HTTPClient请求报错的问题,请问代码是否存在问题?是否需要添加额外请求头?


分析与解决方案

1. 显式指定请求体编码格式

HttpRequest.BodyPublishers.ofString()默认使用UTF-8,但部分服务器需要显式确认编码。可以修改请求体构建逻辑,强制指定UTF-8编码:

.POST(HttpRequest.BodyPublishers.ofString(json1.toString(), StandardCharsets.UTF_8))

2. 添加Postman默认携带的请求头

Postman会自动添加User-Agent等请求头,部分服务器会校验这些标识信息。尝试补充User-Agent头:

HttpRequest httpRequest = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .header("Content-Type", "application/json")
        .header("User-Agent", "PostmanRuntime/7.32.3") // 模拟Postman的User-Agent
        .POST(HttpRequest.BodyPublishers.ofString(json1.toString(), StandardCharsets.UTF_8))
        .build();

3. 生成带格式的JSON字符串

Postman发送的JSON带有换行和缩进,而JSONObject.toString()生成的是紧凑格式。部分服务器对JSON格式有严格要求,可以尝试生成带缩进的JSON:

// 生成带4个空格缩进的JSON字符串
String formattedJson = json1.toString(4);
.POST(HttpRequest.BodyPublishers.ofString(formattedJson, StandardCharsets.UTF_8))

4. 用字节数组发送请求体

避免字符串转字节过程中的编码问题,直接将JSON转为字节数组发送:

byte[] jsonBytes = json1.toString().getBytes(StandardCharsets.UTF_8);
.POST(HttpRequest.BodyPublishers.ofByteArray(jsonBytes))

5. 对比请求详情排查差异

打印HTTPClient发送的所有请求头,和Postman的请求头做对比,找出缺失或不一致的字段:

// 打印所有请求头
httpRequest.headers().map().forEach((key, values) -> {
    System.out.print(key + ": ");
    System.out.println(String.join(", ", values));
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:30:30