如何使用Java Apache HttpClient正确发出POST请求?

问题描述

我正在尝试使用Apache HttpClient5在Java程序中使用Web API。

使用带有curl的简单请求:

curl -X POST -H "x-api-user: d904bd62-da08-416b-a816-ba797c9ee265" -H "x-api-key: xxxxxxxxxxx" https://habitica.com/api/v3/user/class/cast/valorousPresence

我得到了预期的反应和效果

使用我的Java代码

URI uri = new URIBuilder()
              .setScheme("https")
              .setHost("habitica.com")
              .setPath("/api/v3/user/class/cast/valorousPresence")
              .build();
Logger logger = LoggerFactory.getLogger(MyClass.class);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(uri);
httpPost.addHeader(new BasicHeader("x-api-user",getApiUser()));
httpPost.addHeader(new BasicHeader("x-api-key",getApiKey()));
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
logger.info(httpResponse.toString());
return httpResponse.getCode();

运行Java调用时得到的输出

411 Length required HTTP/1.0

我确定我没有正确构建POST调用,应该怎么做?我尝试指定Content-Type,但没有效果。尝试在代码中设置Content-Length会导致编译错误(据我所知,这是由HttpClient5在后台处理的)。 我所有使用HttpClient5的GET请求都可以正常工作。

解决方法

POST始终具有有效负载(内容)。没有内容的POST很不寻常,那么您确定没有忘记什么吗?

即使有效载荷为空,也需要调用setEntity()来设置有效载荷,因为它是设置Content-Length头的实体。

例如您可以调用httpPost.setEntity(new StringEntity("")),它会设置Content-Type: text/plainContent-Length: 0