Spring Boot Download Multiple Files as Zip File

Tags: FileSystemResource zip download zip ZipOutputStream ZipEntry

This Spring Boot tutorial will guide you how to implement download function for a Spring Boot web application which allow user to download multiple files as a .zip file.

Table of contents

  1. Create New Spring Boot Project
  2. Implement Download File Service
  3. Implement Download Controller class and HTML View
  4. Complete Source Code and Run the Web Application
  5. Download Source Code

Create New Spring Boot Project

Open IntelliJ IDEA, select the menu File > New > Project.

On the New Project dialog, select Spring Initializr and click Next button.

Spring Boot Download Multiple Files as Zip File

On the Spring initializr Project Settings dialog input the new project information as below and click Next button.

  • Group: dev.simplesolution
  • Artifact: spring-boot-download-zip
  • Version: 1.0.0
  • Name: spring-boot-download-zip
  • Description: Spring Boot Download Multiple Files as Zip File
  • Package: dev.simplesolution.downloadzip

Spring Boot Download Multiple Files as Zip File

On the Dependencies dialog, select below dependencies and click Next button.

  • Spring Web
  • Thymeleaf

Spring Boot Download Multiple Files as Zip File

Select the location for your project and click Finish button to create new Spring Boot project.

Spring Boot Download Multiple Files as Zip File

You can also create new Spring Boot project using Spring Initializr online tool at start.spring.io as below screenshot.

Spring Boot Download Multiple Files as Zip File

Implement Download File Service

At this step we implement service class to create a .zip file from given file names and write it to the output stream of the HttpServletResponse.

Create a new Java package named dev.simplesolution.downloadzip.service and add new interface named DownloadService to this new package.

src/main/java/dev/simplesolution/downloadzip/service/DownloadService.java

package dev.simplesolution.downloadzip.service;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

public interface DownloadService {
    /**
     * To create and write .zip file to the response's ouput stream.
     * @param response
     * @param listOfFileNames
     */
    void downloadZipFile(HttpServletResponse response, List<String> listOfFileNames);
}

Create a new Java package named dev.simplesolution.downloadzip.service.impl and implement new Java class DownloadServiceImpl as below.

src/main/java/dev/simplesolution/downloadzip/service/impl/DownloadServiceImpl.java

package dev.simplesolution.downloadzip.service.impl;

import dev.simplesolution.downloadzip.service.DownloadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class DownloadServiceImpl implements DownloadService {
    private Logger logger = LoggerFactory.getLogger(DownloadServiceImpl.class);

    @Override
    public void downloadZipFile(HttpServletResponse response, List<String> listOfFileNames) {
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=download.zip");
        try(ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
            for(String fileName : listOfFileNames) {
                FileSystemResource fileSystemResource = new FileSystemResource(fileName);
                ZipEntry zipEntry = new ZipEntry(fileSystemResource.getFilename());
                zipEntry.setSize(fileSystemResource.contentLength());
                zipEntry.setTime(System.currentTimeMillis());

                zipOutputStream.putNextEntry(zipEntry);

                StreamUtils.copy(fileSystemResource.getInputStream(), zipOutputStream);
                zipOutputStream.closeEntry();
            }
            zipOutputStream.finish();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
}

Implement Download Controller class and HTML View

At this step we implement the controller class which expose 2 endpoints.

  • The first endpoint to show the page to allow user click the download button
  • The second endpoint to download the .zip file content.
  • We also implement the method getListOfFileNames() to return list of file names to zip for testing purpose.

Add a new Java package named dev.simplesolution.downloadzip.controller and implement new controller class named DownloadController as below.

src/main/java/dev/simplesolution/downloadzip/controller/DownloadController.java

package dev.simplesolution.downloadzip.controller;

import dev.simplesolution.downloadzip.service.DownloadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

@Controller
public class DownloadController {
    private Logger logger = LoggerFactory.getLogger(DownloadController.class);

    @Autowired
    private DownloadService downloadService;

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @GetMapping("/downloadZipFile")
    public void downloadZipFile(HttpServletResponse response) {
        List<String> listOfFileNames = getListOfFileNames();
        downloadService.downloadZipFile(response, listOfFileNames);
    }

    /**
     * List of file names for testing
     * @return
     */
    private List<String> getListOfFileNames() {
        List<String> listOfFileNames = new ArrayList<>();
        listOfFileNames.add("D:\\SimpleSolution\\order-001.pdf");
        listOfFileNames.add("D:\\SimpleSolution\\order-002.pdf");
        listOfFileNames.add("D:\\SimpleSolution\\order-003.pdf");
        return listOfFileNames;
    }

}

To add the HTML view page add index.html to the templates directory as below. src/main/resources/templates/index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spring Boot Download Zip File - simplesolution.dev</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>
<body class="container">
    <h2>Spring Boot Web Application Download Zip File</h2>
    <a href="http://localhost:8080/downloadZipFile" class="btn btn-primary">Click Here to Download</a>
</body>
</html>

Complete Source Code and Run the Web Application

At this step the complete source code of your Spring Boot web application as following screenshot.

Spring Boot Download Multiple Files as Zip File

Run the web application and open http://localhost:8080/ on your browser to access the web page as below.

Spring Boot Download Multiple Files as Zip File

On the browser, user can click on the button to download .zip file. Below is the screenshot which open the .zip file on 7-Zip application.

Spring Boot Download Multiple Files as Zip File

Download The Source Code

The source code in this article can be found at: github.com/simplesolutiondev/spring-boot-download-zip

or clone at:

git clone https://github.com/simplesolutiondev/spring-boot-download-zip.git

or download at:

Download Source Code

Happy Coding 😊