How to POST JSON request using Apache HttpClient?
JavaJsonHttpPostApache Commons-HttpclientJava Problem Overview
I have something like the following:
final String url = "http://example.com";
final HttpClient httpClient = new HttpClient();
final PostMethod postMethod = new PostMethod(url);
postMethod.addRequestHeader("Content-Type", "application/json");
postMethod.addParameters(new NameValuePair[]{
new NameValuePair("name", "value)
});
httpClient.executeMethod(httpMethod);
postMethod.getResponseBodyAsStream();
postMethod.releaseConnection();
It keeps coming back with a 500. The service provider says I need to send JSON. How is that done with Apache HttpClient 3.1+?
Java Solutions
Solution 1 - Java
Apache HttpClient doesn't know anything about JSON, so you'll need to construct your JSON separately. To do so, I recommend checking out the simple JSON-java library from json.org. (If "JSON-java" doesn't suit you, json.org has a big list of libraries available in different languages.)
Once you've generated your JSON, you can use something like the code below to POST it
StringRequestEntity requestEntity = new StringRequestEntity(
JSON_STRING,
"application/json",
"UTF-8");
PostMethod postMethod = new PostMethod("http://example.com/action");
postMethod.setRequestEntity(requestEntity);
int statusCode = httpClient.executeMethod(postMethod);
Edit
Note - The above answer, as asked for in the question, applies to Apache HttpClient 3.1. However, to help anyone looking for an implementation against the latest Apache client:
StringEntity requestEntity = new StringEntity(
JSON_STRING,
ContentType.APPLICATION_JSON);
HttpPost postMethod = new HttpPost("http://example.com/action");
postMethod.setEntity(requestEntity);
HttpResponse rawResponse = httpclient.execute(postMethod);
Solution 2 - Java
For Apache HttpClient 4.5 or newer version:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://targethost/login");
String JSON_STRING="";
HttpEntity stringEntity = new StringEntity(JSON_STRING,ContentType.APPLICATION_JSON);
httpPost.setEntity(stringEntity);
CloseableHttpResponse response2 = httpclient.execute(httpPost);
Note:
1 in order to make the code compile, both httpclient
package and httpcore
package should be imported.
2 try-catch block has been ommitted.
Reference: appache official guide > the Commons HttpClient project is now end of life, and is no longer > being developed. It has been replaced by the Apache HttpComponents > project in its HttpClient and HttpCore modules
Solution 3 - Java
As mentioned in the excellent answer by janoside, you need to construct the JSON string and set it as a StringEntity
.
To construct the JSON string, you can use any library or method you are comfortable with. Jackson library is one easy example:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.createObjectNode();
node.put("name", "value"); // repeat as needed
String JSON_STRING = node.toString();
postMethod.setEntity(new StringEntity(JSON_STRING, ContentType.APPLICATION_JSON));
Solution 4 - Java
I use JACKSON library to convert object to JSON and set the request body like below. Here is full example.
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost("https://jsonplaceholder.typicode.com/posts");
Post post = new Post("foo", "bar", 1);
ObjectWriter ow = new ObjectMapper().writer();
String strJson = ow.writeValueAsString(post);
System.out.println(strJson);
StringEntity strEntity = new StringEntity(strJson, ContentType.APPLICATION_JSON);
httpPost.setEntity(strEntity);
httpPost.setHeader("Content-type", "application/json");
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
System.out.println(response.getCode() + " " + response.getReasonPhrase());
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
System.out.println(result);
EntityUtils.consume(entity);
} catch (ParseException e) {
e.printStackTrace();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}