I am trying to send a JSON POST request to a URL using HTTPClient in my Springboot application, but I am receiving a 400 status response from the server. However, when I send the same request using Postman, I receive the desired response from the server.
Here's my code:
// 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());
This is the output on the console:
{"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."}
When I hit the same URL via Postman with the following details, I get the desired response from the server:
Request Type: POST
URL: same URL as above
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
} '
Desired Output:
{
"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": []
}
Also, when I use the RestTemplate class, it works fine and I get the desired output on the console but in the actual application I can't use RestTemplate class of springboot so I need help with this.
Is there anything wrong with my code? Do I need to include any additional headers in my request? Any help would be appreciated.
Hopefully this will get you closer. I don't have access to your server.
I have compared what java.net.http.HttpClient sends with what Postman/cURL sends. The only differences I can see are the Accept
, Upgrade
& Http2-Settings
headers, which I have added to the code below. The User-Agent
header is not important. This should not make a difference but perhaps the server you are calling is very particular, eg it can't do http2.
For these sorts of issues I find it very useful to fire requests at httpbin.org. It responds with everything it received.
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import org.json.JSONObject;
public class App
{
public static void main( String[] args ) throws IOException, InterruptedException
{
String url = "http://88.22.199.111:5000/detect";
// or url = "http://httpbin.org/post"; // this is very helpful
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()
.version(Version.HTTP_1_1) // added this
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.header("Accept", "*/*") // added this
.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());
}
}
Perhaps also try RestTemplate
to compare the working headers & payload with the failing ones.