1. Overview

In this tutorial, we're going to look at how we can post forms, files and JSON data using Apache HttpClient 4. In essence, we'll execute HTTP POST requests and set the body of the request with appropriate content.

2. Post Form using Apache HttpClient

To post a form, HttpClient provides us the UrlEncodedFormEntity class.

public void postForm() throws Exception {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        List<NameValuePair> formParameters = new ArrayList<>();
        formParameters.add(new BasicNameValuePair("username", "user1"));
        formParameters.add(new BasicNameValuePair("credentials", "pass1"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParameters, Consts.UTF_8);
        HttpPost httpPost = new HttpPost(POST_URL);
        httpPost.setEntity(entity);
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            handleResponse(response);
        }
    }
}

Here, we're creating some key-value pairs in the formParameters instance. We can think of formParameters as the fields and values of a form. Then we're creating an instance of UrlEncodedFormEntity passing the formParameters list. As the last step, we're creating an HttpPost instance and providing it our UrlEncodedFormEntity object. Note that UrlEncodedFormEntity sets the content type of the HTTP request as application/x-www-form-urlencoded.

There is also another way to post a form using RequestBuilder:

public void postFormWithBuilder() throws Exception {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        final HttpUriRequest postRequest = RequestBuilder.post()
          .setUri(new URI(POST_URL))
          .addParameter("username", "user1")
          .addParameter("credentials", "pass1")
          .build();
        try (CloseableHttpResponse response = httpClient.execute(postRequest)) {
            handleResponse(response);
        }
    }
}

In this example, we aren't using HttpPost but using the RequestBuilder class. Then we're setting the HTTP method, URL and our form parameters on the builder. The resulting POST request will be very similar to the previous one.

3. Upload a File using Apache HttpClient

HttpClient provides the FileEntity class to upload files. 

public void postFormWithFile() throws Exception {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        File file = new File("/notes/todo.txt");
        FileEntity fileEntity = new FileEntity(file, ContentType.create("text/plain", "UTF-8"));
        HttpPost httpPost = new HttpPost(POST_URL);
        httpPost.setEntity(fileEntity);
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            handleResponse(response);
        }
    }
}

Firstly, we're creating an instance of File passing the file location. Then we're creating a FileEntity holding the file and the content type. Lastly, we're creating the POST request and executing it.

4. Post JSON Data using Apache HttpClient

We can also post JSON data using the StringEntity class. We must provide the content type as application/json when creating the StringEntity instance:

public void postFormWithJson() throws Exception {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        StringEntity jsonEntity = new StringEntity("{\"java\":\"byexamples\"}", ContentType.APPLICATION_JSON);
        HttpPost httpPost = new HttpPost(POST_URL);
        httpPost.setEntity(jsonEntity);
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            handleResponse(response);
        }
    }
}

Here, we're providing a valid JSON string to the StringEntity constructor. The content type of StringEntity - application/json - becomes the content type of the request.

5. Summary

In this tutorial, we've investigated how we can post form data, file data or JSON data using Apache HttpClient 4.

Finally, check out the source for all examples over on Github.