HTTP post/API 请求在 bash 上从 CURL 发送时有效,从 Apache http 失败

Posted

技术标签:

【中文标题】HTTP post/API 请求在 bash 上从 CURL 发送时有效,从 Apache http 失败【英文标题】:HTTP post/API request works when sent from CURL on bash, fails from Apache http 【发布时间】:2017-09-14 19:45:29 【问题描述】:

我正在尝试使用 apache http 组件与 Spotify api 交互。我尝试发送的请求在#1 下详细说明了here。当我使用 curl 从 bash 发送此请求时

curl -H "Authorization: Basic SOMETOKEN" -d grant_type=client_credentials https://accounts.spotify.com/api/token

我取回了网站描述的令牌

但是,据我所知,以下 java 代码执行相同的请求,返回 400 错误

代码

    String encoded = "SOMETOKEN";
    CloseableHttpResponse response = null;
    try 
        CloseableHttpClient client = HttpClients.createDefault();
        URI auth = new URIBuilder()
                .setScheme("https")
                .setHost("accounts.spotify.com")
                .setPath("/api/token")
                .setParameter("grant_type", "client_credentials")
                .build();

        HttpPost post = new HttpPost(auth);
        Header header = new BasicHeader("Authorization", "Basic " + encoded);
        post.setHeader(header);
        try 
            response = client.execute(post);
            response.getEntity().writeTo(System.out);
        
        finally 
            response.close();
        
     catch (Exception e) 
        e.printStackTrace();
    

错误

"error":"server_error","error_description":"意外状态:400"

代码打印出来的 URI 是这样的

https://accounts.spotify.com/api/token?grant_type=client_credentials

标题看起来像这样

授权:基本 SOMETOKEN

我没有正确构建请求吗?还是我错过了什么?

【问题讨论】:

【参考方案1】:

对正文中内容类型为application/x-www-form-urlencoded的数据使用表单url编码:

CloseableHttpClient client = HttpClients.createDefault();

HttpPost post = new HttpPost("https://accounts.spotify.com/api/token");
post.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
post.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
StringEntity data = new StringEntity("grant_type=client_credentials");
post.setEntity(data);

HttpResponse response = client.execute(post);

【讨论】:

谢谢!我只需要添加内容类型标头就可以让请求通过。你能解释一下我为什么需要它,或者指出我可以在哪里了解更多关于在请求中添加它的作用吗? 因为这个端点需要这个特定的内容类型。当您使用 curl 指定 -d grant_type=client_credentials 时,您实际上在后台使用了这个特定的内容类型:请参阅 this

以上是关于HTTP post/API 请求在 bash 上从 CURL 发送时有效,从 Apache http 失败的主要内容,如果未能解决你的问题,请参考以下文章

在线GET/POST API接口请求模拟测试工具

在 OS X 上从 zsh 切换到 bash,然后再切换回来?

在同一本地网络上从计算机向手机发出 POST 请求

vue.js中api接口的统一管理(参考)

Node.js POST API 和请求正文的解析

如何在 POST API 中创建请求 ID 并记录它