What is wrong with this POST request implementation?

19,501

Solution 1

You should be using UrlEncodedFormEntity not setParameter on the post. It handles the Content-Type: application/x-www-form-urlencoded header for you too.

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

Solution 2

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

  @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:

<dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>fluent-hc</artifactId>
        <version>${fluent-hc.version}</version>
</dependency>
Share:
19,501
vivek_jonam
Author by

vivek_jonam

@vivek_jonamgooglelinkedin

Updated on June 14, 2022

Comments

  • vivek_jonam
    vivek_jonam almost 2 years

    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:

    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)

    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?

  • mmaceachran
    mmaceachran over 4 years
    This is all deprecated, Do you have an updated example?
  • Parag Kadam
    Parag Kadam over 2 years
    BasicNameValuePair is deprecated now, please update your answer with new APIs.
  • vermap
    vermap about 2 years
    Is there a way to bypass encoding for a certain parameter? Lets say I have 6 parameter in total, 5 above and one more that I don't want to encode as server might not be able to decode that.