Serving a ZIP File in Java with Spring Boot and Downloading It in ReactJS

1 min read

Serving a ZIP File in Java with Spring Boot and Downloading It in ReactJS

This article demonstrates how to implement a REST API in Java using Spring Boot to serve a ZIP file and how to download it from a ReactJS frontend with full example.


1. Backend (Java + Spring Boot)

1.1 Project Setup

Add the necessary dependencies to your pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

1.2 Create a ZIP File and Serve It

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
public class FileDownloadController {

    @GetMapping("/api/download-zip")
    public ResponseEntity<InputStreamResource> downloadZip() throws IOException {
        // Create a temp file to hold the zip
        Path tempZip = Files.createTempFile("example", ".zip");

        try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(tempZip))) {
            // Add files into the zip (in-memory content for example)
            zipOut.putNextEntry(new ZipEntry("hello.txt"));
            zipOut.write("Hello from the ZIP file!".getBytes());
            zipOut.closeEntry();

            zipOut.putNextEntry(new ZipEntry("info.txt"));
            zipOut.write("Some more information.".getBytes());
            zipOut.closeEntry();
        }

        InputStreamResource resource = new InputStreamResource(new FileInputStream(tempZip.toFile()));

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=files.zip")
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .contentLength(Files.size(tempZip))
                .body(resource);
    }
}

2. Frontend (ReactJS)

2.1 Axios Installation

Install Axios for making HTTP requests:

npm install axios

2.2 Download Button Component

import React from 'react';
import axios from 'axios';

const DownloadZip = () => {
  const handleDownload = async () => {
    try {
      const response = await axios.get('http://localhost:8080/api/download-zip', {
        responseType: 'blob'
      });

      // Create a URL for the blob
      const url = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', 'files.zip'); // Specify filename
      document.body.appendChild(link);
      link.click();
      link.remove();
    } catch (error) {
      console.error('Download error:', error);
    }
  };

  return (
    <div>
      <h2>Download ZIP File</h2>
      <button onClick={handleDownload}>Download</button>
    </div>
  );
};

export default DownloadZip;

3. CORS Configuration (Optional)

If your frontend and backend are running on different ports, enable CORS in Spring Boot:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:3000")
                        .allowedMethods("GET", "POST");
            }
        };
    }
}

4. Conclusion

You’ve now created a simple Spring Boot REST API to serve a ZIP file and a ReactJS frontend to download it. This pattern is useful for downloading reports, export files, or any dynamically generated content.

🤞 Never miss a story from us, get weekly updates to your inbox!