java 这个 POST 请求实现有什么问题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15064037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:22:21  来源:igfitidea点击:

What is wrong with this POST request implementation?

javapostapache-httpcomponentsgoogle-oauth

提问by vivek_jonam

I have been working around Google OAuth 2.0 with java and got struck with some unknown error during implementation.
The following CURL for POST request works fine:

我一直在使用 Java 处理 Google OAuth 2.0,但在实现过程中遇到了一些未知错误。
POST 请求的以下 CURL 工作正常:

curl -v -k --header "Content-Type: application/x-www-form-urlencoded" --data "code=4%2FnKVGy9V3LfVJF7gRwkuhS3jbte-5.Arzr67Ksf-cSgrKXntQAax0iz1cDegI&client_id=[my_client_id]&client_secret=[my_client_secret]&redirect_uri=[my_redirect_uri]&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token

And produces the required result.
But the following implementation of above POST request in java causes some error and the response in "invalid_request"
Check the following code and point whats going wrong here:(made use of Apache http-components)

并产生所需的结果。
但是上面的 POST 请求在 java 中的以下实现会导致一些错误和响应"invalid_request"
检查以下代码并指出这里出了什么问题:(使用了 Apache http-components)

HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
HttpParams params = new BasicHttpParams();
params.setParameter("code", code);
params.setParameter("client_id", client_id);
params.setParameter("client_secret", client_secret);
params.setParameter("redirect_uri", redirect_uri);
params.setParameter("grant_type", grant_type);
post.addHeader("Content-Type", "application/x-www-form-urlencoded");
post.setParams(params);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);

Tried with URLEncoder.encode( param , "UTF-8")for each parameter but that too doesn't work.
What might be the cause?

尝试URLEncoder.encode( param , "UTF-8")了每个参数,但这也不起作用。
可能是什么原因?

回答by jdb

You should be using UrlEncodedFormEntitynot setParameter on the post. It handles the Content-Type: application/x-www-form-urlencodedheader for you too.

您应该UrlEncodedFormEntity在帖子中使用not setParameter。它Content-Type: application/x-www-form-urlencoded也为您处理标题。

HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("code", code));
nvps.add(new BasicNameValuePair("client_id", client_id));
nvps.add(new BasicNameValuePair("client_secret", client_secret));
nvps.add(new BasicNameValuePair("redirect_uri", redirect_uri));
nvps.add(new BasicNameValuePair("grant_type", grant_type));

post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);

回答by Alex Efimov

A bit more generic and unified method for sending UrlEncoded request:

发送 UrlEncoded 请求的更通用和统一的方法:

  @SneakyThrows
  public String postUrlEncoded(String context, Map<String, String> body) {
    List<NameValuePair> nameValuePairs = body.entrySet()
          .stream()
          .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
          .collect(Collectors.toList());
    HttpResponse response = Request.Post(baseUrl + context)
          .bodyForm(nameValuePairs)
          .execute().returnResponse();

    return EntityUtils.toString(response.getEntity());
  }

Ps: it requires fluent Apache HTTP client. Pom dependency:

Ps:需要流畅的Apache HTTP客户端。Pom依赖:

<dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>fluent-hc</artifactId>
        <version>${fluent-hc.version}</version>
</dependency>