Spring Boot File Upload and Download REST API

In this tutorial, we will create a REST API for uploading and downloading files using Spring Boot 3. This API will allow clients to upload files to the server and download them later.

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-upload-download
    • Name: file-upload-download
    • Description: File Upload and Download REST API with Spring Boot
    • Package Name: com.example.fileuploaddownload
    • 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

Step 2: Implementing the File Storage Service

2.1 Create a File Storage Service

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

package com.example.fileuploaddownload.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

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

@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 uploaded files will be stored.", ex);
        }
    }

    public String storeFile(MultipartFile file) {
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());

        try {
            if (fileName.contains("..")) {
                throw new RuntimeException("Invalid path sequence " + fileName);
            }

            Path targetLocation = this.fileStorageLocation.resolve(fileName);
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

            return fileName;
        } catch (IOException ex) {
            throw new RuntimeException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

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

Step 3: Creating the REST Controller

3.1 Create the FileController Class

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

package com.example.fileuploaddownload.controller;

import com.example.fileuploaddownload.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 org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;

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

    private final FileStorageService fileStorageService;

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

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        return fileStorageService.storeFile(file);
    }

    @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);
    }
}

3.2 Create the FileUploadDownloadApplication Class

Ensure the FileUploadDownloadApplication class is present in the src/main/java/com/example/fileuploaddownload directory:

package com.example.fileuploaddownload;

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

@SpringBootApplication
public class FileUploadDownloadApplication {

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

Step 4: Running the Application

  1. Open the FileUploadDownloadApplication class in the src/main/java/com/example/fileuploaddownload 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: Testing the Application

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

5.1 Upload a File

  1. Open Postman.
  2. Create a new POST request to http://localhost:8080/api/files/upload.
  3. In the Body tab, select form-data.
  4. Add a key file and select a file to upload.
  5. Send the request.

5.2 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 uploaded.
  3. Send the request and verify that the file is downloaded.

Conclusion

In this tutorial, we created a REST API for uploading and downloading files using Spring Boot 3. We implemented file storage, upload, and download functionalities and tested the API using Postman. This setup provides a solid foundation for developing more complex file management systems.


Comments