Spring Boot File Download Example

In this tutorial, we will create a Spring Boot application that handles file downloads. We will walk through each step, explaining the process and the code required to build a file download functionality.

Prerequisites

Before we start, ensure you have the following:

  • Java Development Kit (JDK) installed
  • Apache Maven installed
  • An IDE (such as IntelliJ IDEA, Eclipse, or VS Code) installed

Step 1: Setting Up the Spring Boot Project

1.1 Create a Spring Boot Project

  1. Open Spring Initializr:

  2. Configure Project Metadata:

    • Project: Maven Project
    • Language: Java
    • Spring Boot: Select the latest version of Spring Boot 3
    • Group: com.example
    • Artifact: file-download
    • Name: file-download
    • Description: File Download Application with Spring Boot
    • Package Name: com.example.filedownload
    • Packaging: Jar
    • Java Version: 17 (or your preferred version)
    • Click Next.
  3. Select Dependencies:

    • On the Dependencies screen, select the dependencies you need:
      • Spring Web
      • Spring Boot DevTools
    • Click Next.
  4. Generate the Project:

    • Click Generate to download the project zip file.
    • Extract the zip file to your desired location.
  5. Open the Project in Your IDE:

    • Open your IDE and import the project as a Maven project.

1.2 Update application.properties

Open the application.properties file located in the src/main/resources directory and add the following configuration:

# File storage location
file.upload-dir=uploads

This configuration sets the directory where files to be downloaded will be stored.

Step 2: Implementing the File Storage Service

2.1 Create a File Storage Service

In the com.example.filedownload.service package, create a new Java class named FileStorageService:

package com.example.filedownload.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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

@Service
public class FileStorageService {

    private final Path fileStorageLocation;

    public FileStorageService(@Value("${file.upload-dir}") String uploadDir) {
        this.fileStorageLocation = Paths.get(uploadDir)
                .toAbsolutePath().normalize();

        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception ex) {
            throw new RuntimeException("Could not create the directory where the files will be stored.", ex);
        }
    }

    public Path loadFileAsResource(String fileName) {
        return this.fileStorageLocation.resolve(fileName).normalize();
    }
}

Explanation:

  • The FileStorageService class manages the file storage.
  • The loadFileAsResource method retrieves the stored file.

Step 3: Creating the REST Controller

3.1 Create the FileController Class

In the com.example.filedownload.controller package, create a new Java class named FileController:

package com.example.filedownload.controller;

import com.example.filedownload.service.FileStorageService;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.nio.file.Path;

@RestController
@RequestMapping("/api/files")
public class FileController {

    private final FileStorageService fileStorageService;

    public FileController(FileStorageService fileStorageService) {
        this.fileStorageService = fileStorageService;
    }

    @GetMapping("/download/{fileName:.+}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
        Path filePath = fileStorageService.loadFileAsResource(fileName);
        Resource resource;

        try {
            resource = new UrlResource(filePath.toUri());
            if (!resource.exists()) {
                throw new RuntimeException("File not found " + fileName);
            }
        } catch (Exception e) {
            throw new RuntimeException("File not found " + fileName, e);
        }

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
    }
}

Explanation:

  • The FileController class handles the file download REST endpoint.
  • The downloadFile method handles file download requests.

3.2 Create the FileDownloadApplication Class

Ensure the FileDownloadApplication class is present in the src/main/java/com/example/filedownload directory:

package com.example.filedownload;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FileDownloadApplication {

    public static void main(String[] args) {
        SpringApplication.run(FileDownloadApplication.class, args);
    }
}

Step 4: Running the Application

  1. Open the FileDownloadApplication class in the src/main/java/com/example/filedownload directory.

  2. Click the green Run button in your IDE or use the terminal to run the application:

    ./mvnw spring-boot:run
    
  3. The application will start on http://localhost:8080.

Step 5: Preparing Files for Download

  1. Create a directory named uploads in the root of your project (at the same level as the src directory).
  2. Place the files you want to be available for download in the uploads directory.

Step 6: Testing the Application

You can use tools like Postman to test the file download functionality.

6.1 Download a File

  1. Open Postman.
  2. Create a new GET request to http://localhost:8080/api/files/download/{fileName}.
    • Replace {fileName} with the name of the file you want to download (e.g., example.txt).
  3. Send the request and verify that the file is downloaded.

Conclusion

In this tutorial, we created a Spring Boot application to handle file downloads. We implemented a file storage service and created a REST endpoint to download files. This setup provides a solid foundation for developing more complex file management systems.


Comments