Download file with RestTemplate

Whether it is image, pdf or word document find out how to download a file with Spring's RestTemplate

Detailed Video Notes

In this tutorial we will show how to download an image from a website.

Project set up

Following the spring boot tutorial and creating a project from spring initializer website we will select web and generate the project. After downloading the project we will import it into eclipse with no further requirements on dependencies.

Getting started

[0:12]

We showed how to make a REST request with RestTemplate and retrieve JSON and with a little configuration you are able to programmatically download a pdf, image (svg, png, gif) or a word document. By default when RestTemplate is initialize it configures a default set of HttpMessageConverter. If you aren't familiar HttpMessageConverter is a strategy with implementation classes that help handle various types of HTTP requests and responses. Since files are binary we need a specific converter ByteArrayHttpMessageConverter to convert the request file.

Default initialization code

public RestTemplate() {
    this.messageConverters.add(new ByteArrayHttpMessageConverter());
    this.messageConverters.add(new StringHttpMessageConverter());
    this.messageConverters.add(new ResourceHttpMessageConverter());
    this.messageConverters.add(new SourceHttpMessageConverter<Source>());
    this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    //...
}

Initialize with messageConverters

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new ByteArrayHttpMessageConverter());

RestTemplate restTemplate = new RestTemplate(messageConverters);

Making the request

[0:48]

Whether we rely on default configuration or set a custom message converter we need to pass in an empty HttpHeaders into HttpEntity. Once this set up is complete a call to restTemplate.exchange can be made. A few parameters need to be specified. First is the location of the file and in this case we will make a request to google's home page logo. Next is the type of HTTP request that should be made and the HttpEnity. Finally spring needs to know what type of class the response should be converted to. Since we are dealing with a binary file, the return type of the request is a byte array.

Once the set up is complete and the request is made we want to ensure that a successful response has been made or notify the program of an error. To do this we will check the HTTP status code and verify it is OK or 200. If it is successful we will use java 7 to write the file to the root directory. Lets run the unit test and verify the file will be written to the project folder root.

@Test
public void fetchFile() throws IOException {

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(
            new ByteArrayHttpMessageConverter());

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));

    HttpEntity<String> entity = new HttpEntity<String>(headers);

    ResponseEntity<byte[]> response = restTemplate.exchange(
            "https://www.google.com/assets/images/srpr/logo11w.png",
            HttpMethod.GET, entity, byte[].class, "1");

    if (response.getStatusCode() == HttpStatus.OK) {
        Files.write(Paths.get("google.png"), response.getBody());
    }
}

Remember anytime you are dealing with files you need to be cognizant of the file size as it could impact the performance of the request. The larger the file most likely the longer it takes to process the request. If processing takes to long you may want to consider async java request

Thanks for joining in today's level up, have a great day!