Published 08 Oct, 2022

Java - Java Unirest sends POST request with empty JSON to server running on localhost but works fine when sending the same request to cloud server?

Category Java
Modified : Nov 28, 2022
72

I am building an agent in Java which has to solve games using a planner. The planner that I am using runs as a service on the cloud, and thus anybody can send HTTP requests to it and get a response. I have to send to it a JSON with the following content: {"domain": "string containing the domain's description", "problem": "string containing the problem to be solved"}. As a response I get a JSON that contains the status and the result, which might be a plan or not, depending on whether there was some problem or not.

The following piece of code allows me to call the planner and receive its response, retrieving the JSON object from the body:

String domain = readFile(this.gameInformation.domainFile);
String problem = readFile("planning/problem.pddl");

// Call online planner and get its response
String url = "http://solver.planning.domains/solve";
HttpResponse<JsonNode> response = Unirest.post(url)
    .header("accept", "application/json")
    .field("domain", domain)
    .field("problem", problem)
    .asJson();

// Get the JSON from the body of the HTTP response
JSONObject responseBody =  response.getBody().getObject();

This code works pefectly fine and I don't have any kind of problem with it. Since I have to do some heavy testing on the agent, I prefer to run the server on localhost, so that the service doesn't get saturated (it can only process one request at a time).

However, if I try to send a request to the server running on localhost, the body of the HTTP request that the server receives is empty. Somehow, the JSON is not sent and I am receiving a response that contains an error.

The following piece of code illustrates how I am trying to send a request to the server running on localhost:

// Call online planner and get its response
String url = "http://localhost:5000/solve";
HttpResponse<JsonNode> response = Unirest.post(url)
    .header("accept", "application/json")
    .field("domain", domain)
    .field("problem", problem)
    .asJson();

For the sake of testing, I had previously created a small Python script that sends the same request to the server running on localhost:

import requests

with open("domains/boulderdash-domain.pddl") as f:
    domain = f.read()

with open("planning/problem.pddl") as f:
    problem = f.read()

data = {"domain": domain, "problem": problem}

resp = requests.post("http://127.0.0.1:5000/solve", json=data)
print(resp)
print(resp.json())

When executing the script, I get a correct response, and it seems that the JSON is sent correctly to the server.

Does anyone know why this is happening?

Answers

There are 1 suggested solutions here and each one has been listed below with a detailed description. The following topics have been covered briefly such as Json, Java, Unirest, Unirest Java. These have been categorized in sections for a clear and precise explanation.

1

Okay, fortunately I have found an answer for this issue (don't try to code/debug at 2-3AM folks, it's never going to turn out right). It seems that the problem was that I was specifying what kind of response I was expecting to get from the server instead of what I was trying to send to it in the request's body:

HttpResponse response = Unirest.post(url) .header("accept", "application/json")...

I was able to solve my problem by doing the following:

// Create JSON object which will be sent in the request's body
JSONObject object = new JSONObject();
object.put("domain", domain);
object.put("problem", problem);

String url = "http://localhost:5000/solve";

<JsonNode> response = Unirest.post(url)
    .header("Content-Type", "application/json")
    .body(object)
    .asJson();

Now I am specifying in the header what type of content I am sending. Also, I have create a JSONObject instance that contains the information that will be added to the request's body. By doing this, it works on both the local and cloud servers.

Despite of this, I still don't really get why when I was calling the cloud server I was able to get a correct response, but it doesn't really matter now. I hope that this answer is helpful for someone who is facing a similar issue!