How to download and save file with apache httpclient in java?

Apache HttpClient is a robust and efficient library for making HTTP requests in Java applications. It provides a wide range of features for working with HTTP, including making GET and POST requests, handling cookies, and managing connection pooling. In this blog post, we will focus on using Apache HttpClient to download files from a remote server. We also cover an example for downloading it with insecure mode. You can learn more about apache httpclient here.

Setting Up Apache HttpClient

Before you can use Apache HttpClient, you need to set up your Java project and add the necessary dependencies. Here’s a simple example of how to do this using Maven:

<dependencies>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
</dependencies>

Make sure to replace the version with the latest available version.

Performing HTTP GET Request

Downloading a file and saving it to a local directory can be easily done using Apache HttpClient. Here’s a short example of how you could implement this:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class DownloadFile {

    public static void main(String[] args) throws Exception {
        String url = "http://example.com/file-to-download";
        String destination = "/path/to/destination/file";

        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet(url);

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

            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();

                if (entity != null) {
                    try (InputStream instream = entity.getContent();
                         OutputStream outstream = new FileOutputStream(destination)) {

                        byte[] buffer = new byte[4096];
                        int len;

                        while ((len = instream.read(buffer)) != -1) {
                            outstream.write(buffer, 0, len);
                        }

                        System.out.println("File downloaded successfully");
                    }
                }

                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

In this example, we’re making a GET request to the specified URL. If the server’s response contains an entity (the file data), we’re saving that to the specified destination file in chunks of 4096 bytes until all data has been read and written. Finally, we close the httpclient.

Remember to replace http://example.com/file-to-download and /path/to/destination/file with your URL and local file path.

Download with insecure mode

If you want to ignore host name verification, which is generally not recommended for production systems due to security concerns, you can create a custom SSL context with a trust manager that doesn’t perform any checks.

Here’s an example of how to achieve that with Apache HttpClient:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class HttpClientExample {

    public static void main(String[] args) throws Exception {
        String url = "https://example.com/file-to-download";
        String destination = "/path/to/destination/file";

        TrustStrategy trustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;  // Accept all certificates
            }
        };

        SSLContext sslContext = SSLContextBuilder
                .create()
                .loadTrustMaterial(trustStrategy)
                .build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                new String[] { "TLSv1.2" }, 
                null,
                NoopHostnameVerifier.INSTANCE);

        CloseableHttpClient httpclient = HttpClients
                .custom()
                .setSSLSocketFactory(sslsf)
                .build();

        try {
            HttpGet httpget = new HttpGet(url);

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

            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();

                if (entity != null) {
                    try (FileOutputStream outstream = new FileOutputStream(new File(destination));
                         FileInputStream instream = (FileInputStream) entity.getContent()) {
                        byte[] buffer = new byte[4096];
                        int len;

                        while ((len = instream.read(buffer)) != -1) {
                            outstream.write(buffer, 0, len);
                        }

                        System.out.println("File downloaded successfully");
                    }
                }
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

This code creates a custom SSL context that trusts all certificates and bypasses host name verification, and uses this context to create the HttpClient.

Again, please remember to replace https://example.com/file-to-download and /path/to/destination/file with your URL and local file path.

Remember that ignoring SSL certificates and host name verification is a security risk and should typically only be done when connecting to trusted servers or for testing purposes.

Leave a Reply

Your email address will not be published. Required fields are marked *