Apache HTTPClient POST 到 REST 服务的方式与 cURL 不同

Posted

技术标签:

【中文标题】Apache HTTPClient POST 到 REST 服务的方式与 cURL 不同【英文标题】:Apache HTTPClient POSTs to REST service differently than cURL 【发布时间】:2020-06-24 13:49:39 【问题描述】:

我正在尝试用Apache http client 4.5.5REST API。我可以像这样使用cURL 成功地将POST 发送到API:

curl -X POST --user username:password  --header "Content-Type: application/json" --data "@/path/to/file.json" https://some.restfulapi.com/endpoint

但是,当我尝试使用 Apache http 客户端 POST 到 API 时,使用相同的凭据时它总是失败并显示 HTTP 错误代码:401 Unauthorized

HttpClient httpclient = new DefaultHttpClient();

CredentialsProvider credentialsPovider = new BasicCredentialsProvider();
credentialsPovider.setCredentials(new AuthScope(request.getHost(), 443),  new UsernamePasswordCredentials(user, password));
                

HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credentialsPovider);


HttpPost httppost = new HttpPost(request.getHost()); 


// append headers
for(Header header : request.getHeaders())
    httppost.addHeader(header.getKey(), header.getValue());

                
if(body_entity.length()>0)
    // append the  data to the post
    StringEntity stringentity = new StringEntity(body_entity, HTTP.UTF_8);
    stringentity.setContentType(content_type);
    httppost.setEntity(stringentity);                                           



HttpResponse response = httpclient.execute(httppost, context);

我也尝试将身份验证直接添加为标头:

String encoding = Base64.getEncoder().encodeToString((user + ":" + password);
httppost.addHeader("Authentication", encoding);

也返回一个401 Unauthorized

此外,直接标头变体:

- httppost.addHeader("user", "Basic " + encoding);
- httppost.addHeader("Authentication", "Basic " + encoding);
- httppost.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials(user, password), "UTF-8", false));

所有结果都导致400 Bad request 响应。

将 HttpClientBuilder 与 CredentialsProvider 一起使用

HttpClientBuilder clientbuilder = HttpClients.custom();
clientbuilder = clientbuilder.setDefaultCredentialsProvider(credentialsPovider);
httpclient = clientbuilder.build();

也会导致400 Bad request 响应。

如何创建一个 Apache http 客户端 POST 请求来执行以下操作 cURL 实用程序是干什么的? cURL 与 Apache 有何不同 http客户端?编码(UTF-8)可能是问题吗?

其他帖子和文档:

cUrl to apache HttpClient convert curl to httpclient post Apache HTTP authentication

【问题讨论】:

认证头不是“user”而是“Authentication” @f1sh。我也试过那个标题标签。请参阅编辑后的帖子。 甚至不是Authentication,而是Authorization。它称为授权标头。此外,当您在第二个示例中将编码的凭据附加到 Basic 时,您会丢失一个空格。应该是"Basic " + encoding 为了帮助您找到答案,您应该检查如何记录实际的 HTTP 请求并将其与 cURL 生成的内容进行比较。你肯定会看到那里有什么不同。 @Krisz。即使使用Authorization 作为标题而不是Authentication - 400 响应。 【参考方案1】:

您可能错过了“基本”空格,请尝试“基本”

【讨论】:

空间在那里。 尝试授权而不是身份验证 谢谢,但也已经尝试过了。请参阅 cmets。【参考方案2】:

解决方案

httppost.addHeader("Authorization", "Basic "+Base64.getEncoder().encodeToString("user:password".getBytes()));

加上缺少的(和必需的 - 未记录的)标题:

httppost.addHeader("Content-Length", json.toString().length);

【讨论】:

以上是关于Apache HTTPClient POST 到 REST 服务的方式与 cURL 不同的主要内容,如果未能解决你的问题,请参考以下文章

httpclient post请求实例(自己写的)

Android 项目使用 httpclient --> http.client (apache), post/get 方法

Use Apache HttpClient to Post json data

Java使用HttpClient实现Post请求

HttpClient一个http_post请求例子

java HttpClient POST请求