Spring Boot File Download Example

View more categories:

1- Objective of Lesson

In this lesson, I am going to show you how to create a  Spring Boot application which has functions to download files from the Web Server to a local computer, for example, photo, zip, pdf files, etc.
Below is some ways for creating the file downloading function:
  1. ResponseEntity<InputStreamResource>: Write a method to return ResponseEntity. This object wraps an  InputStreamResource object (which is data of the file downloaded by user).
  2. ResponseEntity<ByteArrayResource>: Write a method to return  ResponseEntity. This object wraps the  ByteArrayResource object (which is data of the file downloaded by user).
  3. HttpServletRespone: Write the data of the file to be downloaded directly into the HttpServletRespone.
For big size files, an user should, when downloading, wait for a period of time. You need to provide some following information to the browser:

Content-Disposition

Content-Disposition: means information on the  Header part of  Response. It shows the contents expected to be displayed on the browser.
  • inline: Content that will display automatically.
  • attachment: Attached file
  • form-data: Form data.
  • ....
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="java-tutorial.pdf"

Content-Length

contentLength: This is the size of content (Unit:  byte). This information helps the browser to inform to users of the size of content prepared to be downloaded. Therefore, while downloading the browser, it is possible to notify to users of the number of bytes downloaded, display percentage downloaded, estimate remaining time.

Content-Type

This information helps the browser to know which applications can open this content and suggest users to open by a program available on their computer when the content is downloaded successfully. Set  Content-Type=application/octet-stream if you want the browser to download such content immediately without asking users.
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="picture.png"


Content-Type: image/png
Content-Disposition: attachment; filename="picture.png"


Content-Type: image/png
Content-Disposition: inline; filename="picture.png"
See more:

2- Create Spring Boot project

3- ResponseEntity

Write a method to return  ResponseEntity. This object wraps the  InputStreamResource object (which is data of the file downloaded by user).
Example1Controller.java
package org.o7planning.sbdownload.controller;

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

import javax.servlet.ServletContext;

import org.o7planning.sbdownload.utils.MediaTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class Example1Controller {

    private static final String DIRECTORY = "C:/PDF";
    private static final String DEFAULT_FILE_NAME = "java-tutorial.pdf";

    @Autowired
    private ServletContext servletContext;

    // http://localhost:8080/download1?fileName=abc.zip
    // Using ResponseEntity<InputStreamResource>
    @RequestMapping("/download1")
    public ResponseEntity<InputStreamResource> downloadFile1(
            @RequestParam(defaultValue = DEFAULT_FILE_NAME) String fileName) throws IOException {

        MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(this.servletContext, fileName);
        System.out.println("fileName: " + fileName);
        System.out.println("mediaType: " + mediaType);

        File file = new File(DIRECTORY + "/" + fileName);
        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

        return ResponseEntity.ok()
                // Content-Disposition
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
                // Content-Type
                .contentType(mediaType)
                // Contet-Length
                .contentLength(file.length()) //
                .body(resource);
    }

}
MediaTypeUtils.java
package org.o7planning.sbdownload.utils;

import javax.servlet.ServletContext;

import org.springframework.http.MediaType;

public class MediaTypeUtils {

    // abc.zip
    // abc.pdf,..
    public static MediaType getMediaTypeForFileName(ServletContext servletContext, String fileName) {
        // application/pdf
        // application/xml
        // image/gif, ...
        String mineType = servletContext.getMimeType(fileName);
        try {
            MediaType mediaType = MediaType.parseMediaType(mineType);
            return mediaType;
        } catch (Exception e) {
            return MediaType.APPLICATION_OCTET_STREAM;
        }
    }
    
}

4- ResponseEntity

Write a method to return  ResponseEntity. This object wraps the  ByteArrayResource object (which is data of the file downloaded by user).
Example2Controller.java
package org.o7planning.sbdownload.controller;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.servlet.ServletContext;

import org.o7planning.sbdownload.utils.MediaTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class Example2Controller {

    private static final String DIRECTORY = "C:/PDF";
    private static final String DEFAULT_FILE_NAME = "java-tutorial.pdf";

    @Autowired
    private ServletContext servletContext;

    // http://localhost:8080/download2?fileName=abc.zip
    // Using ResponseEntity<ByteArrayResource>
    @GetMapping("/download2")
    public ResponseEntity<ByteArrayResource> downloadFile2(
            @RequestParam(defaultValue = DEFAULT_FILE_NAME) String fileName) throws IOException {

        MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(this.servletContext, fileName);
        System.out.println("fileName: " + fileName);
        System.out.println("mediaType: " + mediaType);

        Path path = Paths.get(DIRECTORY + "/" + DEFAULT_FILE_NAME);
        byte[] data = Files.readAllBytes(path);
        ByteArrayResource resource = new ByteArrayResource(data);

        return ResponseEntity.ok()
                // Content-Disposition
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + path.getFileName().toString())
                // Content-Type
                .contentType(mediaType) //
                // Content-Lengh
                .contentLength(data.length) //
                .body(resource);
    }

}

5- HttpServletRespone

Write the data of the file to be downloaded directly into the  HttpServletRespone.
Example3Controller.java
package org.o7planning.sbdownload.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;

import org.o7planning.sbdownload.utils.MediaTypeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class Example3Controller {

    private static final String DIRECTORY = "C:/PDF";
    private static final String DEFAULT_FILE_NAME = "java-tutorial.pdf";

    @Autowired
    private ServletContext servletContext;

    // http://localhost:8080/download3?fileName=abc.zip
    // Using HttpServletResponse
    @GetMapping("/download3")
    public void downloadFile3(HttpServletResponse resonse,
            @RequestParam(defaultValue = DEFAULT_FILE_NAME) String fileName) throws IOException {

        MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(this.servletContext, fileName);
        System.out.println("fileName: " + fileName);
        System.out.println("mediaType: " + mediaType);

        File file = new File(DIRECTORY + "/" + fileName);

        // Content-Type
        // application/pdf
        resonse.setContentType(mediaType.getType());

        // Content-Disposition
        resonse.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName());

        // Content-Length
        resonse.setContentLength((int) file.length());

        BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream outStream = new BufferedOutputStream(resonse.getOutputStream());

        byte[] buffer = new byte[1024];
        int bytesRead = 0;
        while ((bytesRead = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, bytesRead);
        }
        outStream.flush();
        inStream.close();
    }

}

View more categories: