首页 > 解决方案 > Java Unirest 将带有空 JSON 的 POST 请求发送到在 localhost 上运行的服务器,但是在将相同的请求发送到云服务器时工作正常?

问题描述

我正在用 Java 构建一个代理,它必须使用计划器来解决游戏。我使用的规划器在云上作为服务运行,因此任何人都可以向它发送 HTTP 请求并获得响应。我必须向它发送JSON以下内容:{"domain": "string containing the domain's description", "problem": "string containing the problem to be solved"}. 作为响应,我得到一个JSON包含状态和结果的结果,这可能是一个计划,也可能不是一个计划,具体取决于是否存在问题。

以下代码允许我调用规划器并接收其响应,从正文中检索 JSON 对象:

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();

这段代码工作得很好,我没有任何问题。由于我必须对代理进行一些繁重的测试,我更喜欢在 localhost 上运行服务器,这样服务就不会饱和(一次只能处理一个请求)。

但是,如果我尝试向在 localhost 上运行的服务器发送请求,则服务器接收到的 HTTP 请求的正文为空。不知何故,未发送 JSON,我收到包含错误的响应。

以下代码说明了我如何尝试向在 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();

为了测试,我之前创建了一个小的 Python 脚本,它将相同的请求发送到在 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())

执行脚本时,我得到了正确的响应,并且似乎 JSON 已正确发送到服务器。

有谁知道为什么会这样?

标签: javajsonunirestunirest-java

解决方案


好的,幸运的是我找到了这个问题的答案(不要尝试在凌晨 2 点到 3 点进行编码/调试,这永远不会正确)。似乎问题在于我指定了我期望从服务器获得的响应类型,而不是我试图在请求正文中发送给它的响应:

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

我能够通过执行以下操作来解决我的问题:

// 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();

现在我在标题中指定我发送的内容类型。此外,我创建了一个JSONObject实例,其中包含将添加到请求正文中的信息。通过这样做,它可以在本地和云服务器上运行。

尽管如此,我仍然不明白为什么当我调用云服务器时我能够得到正确的响应,但现在这并不重要。我希望这个答案对面临类似问题的人有所帮助!


推荐阅读