javaapache-httpclient-4.xapache-httpcomponents

Apache HttpClient post request with non string values in body


I'm using Apache HttpClient version 4.5.13 and I'm having trouble creating my POST request body. From the tutorials I've seen online, they tell me to use NameValuePair when creating the request entity. However, NameValuePair only accepts String for the values.

How can I set Integer, Double, and Booleans as well? The API I'm calling has a mixture of them in the JSON body. For example, my body can look like this:

{
  "id": 3,
  "name": "Test",
  "accepted": false,
  "street": "foo bar ave."
}

This is how the documentations recommend I create the body:

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

public static void main(String[] args) {
    List<NameValuePair> body = new ArrayList<NameValuePair>();
    body.add(new BasicNameValuePair("id", Integer.valueOf(3)));
    body.add(new BasicNameValuePair("name", "Test"));
    body.add(new BasicNameValuePair("accepted", Boolean.valueOf(false)));
    body.add(new BasicNameValuePair("street", "foo bar ave."));
    
    HttpPost httpPost = new HttpPost("http://my-url.com/test-api");
    httpPost.setEntity(new UrlEncodedFormEntity(body));
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-Type", "application/json");
    
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse response = httpClient.execute(httpPost);
    
    // etc...
}

But as you can see, I have to convert everything to String which the API I'm calling rejects because of the mismatch of data types. Is there some other way I can create the request which accepts various data types?


Solution

  • I was able to fix this by using StringEntity. I converted the code in the question to the following:

    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.json.JSONObject;
    
    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", 3);
        jsonObject.put("name", "Test");
        jsonObject.put("accepted", false);
        jsonObject.put("street", "foo bar ave.");
        
        HttpPost httpPost = new HttpPost("http://my-url.com/test-api");
        httpPost.setEntity(new StringEntity(jsonObject.toString()));
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-Type", "application/json");
        
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = httpClient.execute(httpPost);
        
        // etc...
    }
    

    And I was able to call the API in question without any errors. Hopefully, this helps someone!