Apache HttpClient Upload File Example

In this article, we will illustrate how to do a multipart upload operation using Apache HttpClient 4.5+.
We’ll use http://httpbin.org/post as a test server because it’s public and it accepts most types of content.
Related Apache HttpClient useful articles:
If you want to dig deeper and learn other cool things you can do with the HttpClient – head on over to the main HttpClient tutorial.

Maven dependencies

We use maven to manage our dependencies and are using Apache HttpClient version 4.5. Add the following dependency to your project.
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.developersguide.httpclient</groupId>
    <artifactId>apache-httpclient-guide</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <description></description>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Multipart File Upload

1. Create instance of CloseableHttpClient using helper class HttpClients.

CloseableHttpClient httpclient = HttpClients.createDefault()
The HttpClients.createDefault() method creates CloseableHttpClient instance with default configuration.

2. Build multipart upload request

// build multipart upload request
HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, file.getName())
.addTextBody("text", message, ContentType.DEFAULT_BINARY).build();

3. Build HTTP request and assign multipart upload data

HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, file.getName())
.addTextBody("text", message, ContentType.DEFAULT_BINARY).build();
HttpUriRequest request = RequestBuilder.post("http://httpbin.org/post").setEntity(data).build();

4. Create a custom response handler

ResponseHandler<String> responseHandler = response -> {
 int status = response.getStatusLine().getStatusCode();
 if (status >= 200 && status < 300) {
  HttpEntity entity = response.getEntity();
  return entity != null ? EntityUtils.toString(entity) : null;
 } else {
  throw new ClientProtocolException("Unexpected response status: " + status);
 }
};
A more direct way to create a multipart entity is to use the addBinaryBody and AddTextBody methods. These methods work for uploading text, files, character arrays, and InputStream objects.
Let's create an HttpEntity using the MultipartEntityBuilder. When we created the builder, we add a binary body – containing the file that’ll be uploaded and also a text body.
package com.javadevelopersguide.httpclient.examples;

import java.io.File;
import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * This example demonstrates the use of {@link HttpPost} request method.
 * And sending Multipart Form requests
 * @author Ramesh Fadatare
 */
public class HttpClientMultipartUploadExample {
    public static void main(String...args) throws IOException {

        try (CloseableHttpClient httpclient = HttpClients.createDefault()) {

            File file = new File("demo.png");
            String message = "This is a multipart post";

            // build multipart upload request
            HttpEntity data = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, file.getName())
                .addTextBody("text", message, ContentType.DEFAULT_BINARY).build();

            // build http request and assign multipart upload data
            HttpUriRequest request = RequestBuilder.post("http://httpbin.org/post").setEntity(data).build();

            System.out.println("Executing request " + request.getRequestLine());

            // Create a custom response handler
            ResponseHandler < String > responseHandler = response - > {
                int status = response.getStatusLine().getStatusCode();
                if (status >= 200 && status < 300) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            };
            String responseBody = httpclient.execute(request, responseHandler);
            System.out.println("----------------------------------------");
            System.out.println(responseBody);
        }
    }
}

Output

Executing request POST http://httpbin.org/post HTTP/1.1
----------------------------------------
{
  "args": {}, 
  "data": "", 
  "files": {
    "upfile": "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAAA0YAAADmCAYAAADx0JVrAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJ..."
  }, 
  "form": {
    "text": "This is a multipart post"
  }, 
  "headers": {
    "Accept-Encoding": "gzip,deflate", 
    "Connection": "close", 
    "Content-Length": "9527", 
    "Content-Type": "multipart/form-data; boundary=IJeEBy_OHEtuA2sJyD2wp9S7YXhruSRMLYg4Z", 
    "Host": "httpbin.org", 
    "User-Agent": "Apache-HttpClient/4.5 (Java/1.8.0_172)"
  }, 
  "json": null, 
  "origin": "49.35.12.218", 
  "url": "http://httpbin.org/post"
}

Using the AddPart Method

Let’s start by looking at the MultipartEntityBuilder object to add parts to an Http entity which will then be uploaded via a POST operation.
This is a generic method to add parts to an HttpEntity representing the form. Let's look at sample code example:
package com.javadevelopersguide.httpclient.siteexamples;

import java.io.File;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * Example how to use multipart/form encoded POST request.
 */
public class ClientMultipartFormPost {

    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            System.out.println("File path not given");
            System.exit(1);
        }
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost("http://localhost:8080" +
                "/servlets-examples/servlet/RequestInfoExample");

            FileBody bin = new FileBody(new File(args[0]));
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                .addPart("bin", bin)
                .addPart("comment", comment)
                .build();


            httppost.setEntity(reqEntity);

            System.out.println("executing request " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}
Check out https://www.baeldung.com/httpclient-multipart-upload article to know more uploading a Byte Array, Text, Zip File, an Image File, and a Text Part.

References

Comments