Posting with HttpClient

1. Overview

In this tutorial – we’ll POST with the HttpClient 4 – using first authorization, then the fluent HttpClient API.

Finally, we’ll discuss how to Upload a File Using Httpclient.

2. Basic POST

First, let’s go over a simple example and send a POST request using HttpClient.

We’ll do a POST with two parameters – “username” and “password“:

@Test
public void whenSendPostRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("username", "John"));
    params.add(new BasicNameValuePair("password", "pass"));
    httpPost.setEntity(new UrlEncodedFormEntity(params));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we used a List of NameValuePair to include parameters in the POST request.

3. POST With Authorization

Next, let’s see how to do a POST with Authentication credentials using the HttpClient.

In the following example – we send a POST request to a URL secured with Basic Authentication by adding an Authorization header:

@Test
public void whenSendPostRequestWithAuthorizationUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException, AuthenticationException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.maixuanviet.com");

    httpPost.setEntity(new StringEntity("test post"));
    UsernamePasswordCredentials creds
      = new UsernamePasswordCredentials("John", "pass");
    httpPost.addHeader(new BasicScheme().authenticate(creds, httpPost, null));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

4. POST With JSON

Now – let’s see how to send a POST request with a JSON body using the HttpClient.

In the following example – we’re sending some person information (id, name) as JSON:

@Test
public void whenPostJsonUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.maixuanviet.com");

    String json = "{"id":1,"name":"John"}";
    StringEntity entity = new StringEntity(json);
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we’re using the StringEntity to set the body of the request.

We’re also setting the ContentType header to application/json to give the server the necessary information about the representation of the content we’re sending.

5. POST With the HttpClient Fluent API

Next, let’s POST with the HttpClient Fluent API.

We’re going to send a request with two parameters “username” and “password“:

@Test
public void whenPostFormUsingHttpClientFluentAPI_thenCorrect() 
  throws ClientProtocolException, IOException {
    HttpResponse response = Request.Post("http://www.maixuanviet.com").bodyForm(
      Form.form().add("username", "John").add("password", "pass").build())
      .execute().returnResponse();

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

6. POST Multipart Request

Now, let’s POST a Multipart Request.

We’ll post a File, username, and password using MultipartEntityBuilder:

@Test
public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.maixuanviet.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("username", "John");
    builder.addTextBody("password", "pass");
    builder.addBinaryBody(
      "file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");

    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. Upload a File Using HttpClient

Next, let’s see how to upload a File using the HttpClient.

We’ll upload the “test.txt” file using MultipartEntityBuilder:

@Test
public void whenUploadFileUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.maixuanviet.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody(
      "file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

8. Get File Upload Progress

Finally – let’s see how to get the progress of File upload using HttpClient.

In the following example, we’ll extend the HttpEntityWrapper to gain visibility into the upload process.

First – here’s the upload method:

@Test
public void whenGetUploadFileProgressUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.maixuanviet.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody(
      "file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    HttpEntity multipart = builder.build();

    ProgressEntityWrapper.ProgressListener pListener = 
      percentage -> assertFalse(Float.compare(percentage, 100) > 0);
    httpPost.setEntity(new ProgressEntityWrapper(multipart, pListener));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

We’ll also add the interface ProgressListener that enables us to observe the upload progress:

public static interface ProgressListener {
    void progress(float percentage);
}

And here’s our extended version of HttpEntityWrapper ProgressEntityWrapper“:

public class ProgressEntityWrapper extends HttpEntityWrapper {
    private ProgressListener listener;

    public ProgressEntityWrapper(HttpEntity entity, ProgressListener listener) {
        super(entity);
        this.listener = listener;
    }

    @Override
    public void writeTo(OutputStream outstream) throws IOException {
        super.writeTo(new CountingOutputStream(outstream, listener, getContentLength()));
    }
}

And the extended version of FilterOutputStream “CountingOutputStream“:

public static class CountingOutputStream extends FilterOutputStream {
    private ProgressListener listener;
    private long transferred;
    private long totalBytes;

    public CountingOutputStream(
      OutputStream out, ProgressListener listener, long totalBytes) {
        super(out);
        this.listener = listener;
        transferred = 0;
        this.totalBytes = totalBytes;
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        out.write(b, off, len);
        transferred += len;
        listener.progress(getCurrentProgress());
    }

    @Override
    public void write(int b) throws IOException {
        out.write(b);
        transferred++;
        listener.progress(getCurrentProgress());
    }

    private float getCurrentProgress() {
        return ((float) transferred / totalBytes) * 100;
    }
}

Note that:

  • When extending FilterOutputStream to “CountingOutputStream” – we are overriding the write() method to count the written (transferred) bytes
  • When extending HttpEntityWrapper to “ProgressEntityWrapper” – we are overriding the writeTo() method to use our “CountingOutputStream”

9. Conclusion

In this tutorial, we illustrated the most common ways to send POST HTTP Requests with the Apache HttpClient 4.

We learned how to send a POST request with Authorization, how to post using HttpClient fluent API and how to upload a file and track its progress.

The implementation of all these examples and code snippets can be found in the github project.

Related posts:

RegEx for matching Date Pattern in Java
Java Program to Implement Triply Linked List
Reactive Flow with MongoDB, Kotlin, and Spring WebFlux
Giới thiệu Google Guice – Binding
Java Program to Check Cycle in a Graph using Topological Sort
Tạo ứng dụng Java RESTful Client không sử dụng 3rd party libraries
Mệnh đề if-else trong java
Check If a String Is Numeric in Java
Java Program to Solve any Linear Equation in One Variable
Java Program to Implement Sorted Circularly Singly Linked List
Java Program to Implement RoleUnresolvedList API
Configure a RestTemplate with RestTemplateBuilder
Lớp lồng nhau trong java (Java inner class)
Hướng dẫn Java Design Pattern – Iterator
Java InputStream to Byte Array and ByteBuffer
Java Program to Implement Solovay Strassen Primality Test Algorithm
Cachable Static Assets with Spring MVC
Uploading MultipartFile with Spring RestTemplate
Java Program to Implement Fisher-Yates Algorithm for Array Shuffling
Java Program to Implement Traveling Salesman Problem using Nearest neighbour Algorithm
Spring Security Registration – Resend Verification Email
Introduction to Spring Cloud CLI
Spring Security Authentication Provider
Java – Write to File
Filtering and Transforming Collections in Guava
Java Program to Find Median of Elements where Elements are Stored in 2 Different Arrays
Java Program to Implement AVL Tree
Spring Cloud Series – The Gateway Pattern
Java Program to Implement Disjoint Set Data Structure
Java Program to Perform LU Decomposition of any Matrix
JPA/Hibernate Persistence Context
Java Program to Implement Hash Tables Chaining with List Heads