How to download a file via HTTP GET and HTTP POST in Java without using any external libraries
Apart from uploading a file to a HTTP server endpoint, another common task for a Java HTTP client is to download a file from a HTTP server. Even though there are many Java external libraries to help us do so, using the facilities in the Java standard runtime installation is not difficult. Furthermore, we will be able to keep our Java application leaner if we can download files without additional dependencies.
In case you need a reference, this is how to download a file via HTTP GET and HTTP POST in Java without using any external libraries.
Downloading a file from a HTTP server endpoint via HTTP GET
Generally, downloading a file from a HTTP server endpoint via HTTP GET consists of the following steps:
- Construct the HTTP GET request to send to the HTTP server.
- Send the HTTP request and receive the HTTP Response from the HTTP server.
- Save the contents of the file from HTTP Response to a local file.
Java codes to download a file from a HTTP server endpoint via HTTP GET
Given these points, let us modify the codes from how to send a HTTP GET request in Java to save the contents of the file from a HTTP Response to a local file:
import java.io.IOException; import java.io.FileOutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; public class HttpGetDownloadFileExample { public static void main(String[] args) { ReadableByteChannel readableChannelForHttpResponseBody = null; FileChannel fileChannelForDownloadedFile = null; try { // Define server endpoint URL robotsUrl = new URL("http://www.techcoil.com/robots.txt"); HttpURLConnection urlConnection = (HttpURLConnection) robotsUrl.openConnection(); // Get a readable channel from url connection readableChannelForHttpResponseBody = Channels.newChannel(urlConnection.getInputStream()); // Create the file channel to save file FileOutputStream fosForDownloadedFile = new FileOutputStream("robots.txt"); fileChannelForDownloadedFile = fosForDownloadedFile.getChannel(); // Save the body of the HTTP response to local file fileChannelForDownloadedFile.transferFrom(readableChannelForHttpResponseBody, 0, Long.MAX_VALUE); } catch (IOException ioException) { System.out.println("IOException occurred while contacting server."); } finally { if (readableChannelForHttpResponseBody != null) { try { readableChannelForHttpResponseBody.close(); } catch (IOException ioe) { System.out.println("Error while closing response body channel"); } } if (fileChannelForDownloadedFile != null) { try { fileChannelForDownloadedFile.close(); } catch (IOException ioe) { System.out.println("Error while closing file channel for downloaded file"); } } } } }
As shown above, we had created a class with a main method. When the main method is executed, our Java program does several things.
Firstly, we had declared an instance of ReadableByteChannel
and an instance of FileChannel
to contain null values so as to facilitate closure in the finally
block.
After we had done so, we define a try
block for running the file download logic that may throw checked exceptions.
Within the try
block, we first use an instance of URL to get an instance of HttpURLConnection
that points to a HTTP server endpoint for the file that we wish to download.
Once we have done so, we get an instance of ReadableByteChannel
that is mapped to the input stream of urlConnection
. In addition, we set it to the readableChannelForHttpResponseBody
variable for manipulation later.
After we had an instance of ReadableByteChannel
, we then proceed to get a FileChannel that will point to a local file path where we want to save the downloaded file. In this case, we want to save the downloaded file as robots.txt
in the same directory where we run our Java program.
Finally, we use fileChannelForDownloadedFile.transferFrom
method on readableChannelForHttpResponseBody
to save the contents of the HTTP response body to the local file.
Downloading a file from a HTTP server endpoint via HTTP POST
There can be cases where the client need to supply some information to the HTTP server in order to download a file. In such a situation, HTTP POST is a more appropriate HTTP method to use for downloading the file.
As with HTTP GET, downloading of a file from the HTTP server via HTTP POST consists of the following steps:
- Construct the HTTP POST request to send to the HTTP server.
- Send the HTTP request and receive the HTTP Response from the HTTP server.
- Save the contents of the file from HTTP Response to a local file.
Java codes to download a file from a HTTP server endpoint via HTTP POST
Given these points, let's modify the Java code from how to send a HTTP POST request in Java to save the contents of the file from a HTTP Response to a local file:
import java.io.BufferedWriter; import java.io.IOException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; public class HTTPPostDownloadFileExample { public static void main(String[] args) throws IOException { // Define the server endpoint to send the HTTP request to URL serverUrl = new URL("https://www.techcoil.com/process/proof-of-concepts/userNameAndLuckyNumberTextFileGeneration"); HttpURLConnection urlConnection = (HttpURLConnection)serverUrl.openConnection(); // Indicate that we want to write to the HTTP request body urlConnection.setDoOutput(true); urlConnection.setRequestMethod("POST"); // Writing the post data to the HTTP request body BufferedWriter httpRequestBodyWriter = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream())); httpRequestBodyWriter.write("visitorName=Johnny+Jacobs&luckyNumber=1234"); httpRequestBodyWriter.close(); // Get a readable channel from url connection ReadableByteChannel readableChannelForHttpResponseBody = Channels.newChannel(urlConnection.getInputStream()); // Create the file channel to save file FileOutputStream fosForDownloadedFile = new FileOutputStream("luckyNumber.txt"); FileChannel fileChannelForDownloadedFile = fosForDownloadedFile.getChannel(); // Save the contents of HTTP response to local file fileChannelForDownloadedFile.transferFrom(readableChannelForHttpResponseBody, 0, Long.MAX_VALUE); } }
As shown above, we had created a class with a main method which will propagate any occurrences of IOException back to the caller. When the main method is executed, our Java program does several things.
First, it creates an instance of HttpURLConnection
, urlConnection
, that maps to the HTTP server endpoint at https://www.techcoil.com/process/proof-of-concepts/userNameAndLuckyNumberTextFileGeneration
. Given that, we then configure urlConnection
to allow us to write to the HTTP request body via urlConnection.setDoOutput(true). After that, we set the HTTP method of the HTTP request as POST via urlConnection.setRequestMethod("POST")
.
Next, we use an instance of BufferedWriter to write some POST variables to the HTTP request body.
Once we had written the POST variables, we then get an instance of ReadableByteChannel
from the input stream of urlConnection
. Given that instance, we will then be able to read from the body of the HTTP response.
After we had an instance of ReadableByteChannel
, we then proceed to get an instance of FileChannel
that will point to a local file path where we want to save the downloaded file. In this case, we will save the downloaded file as luckyNumber.txt
in the same directory where we run our Java program.
Finally, we use fileChannelForDownloadedFile.transferFrom
on readableChannelForHttpResponseBody
to save the contents of the HTTP response body to the local file.