Spring Boot File Upload Example

In this tutorial, we will create a Spring Boot application that handles file uploads. We will walk through each step, explaining the process and the code required to build a file upload 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-upload
    • Name: file-upload
    • Description: File Upload Application with Spring Boot
    • Package Name: com.example.fileupload
    • 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 uploaded files will be stored.

Step 2: Implementing the File Storage Service

2.1 Create a File Storage Service

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

package com.example.fileupload.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();
    }
}

Explanation:

  • The FileStorageService class manages the file storage.
  • The storeFile method stores the uploaded file in the configured directory.
  • The loadFileAsResource method retrieves the stored file.

Step 3: Creating the REST Controller

3.1 Create the FileController Class

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

package com.example.fileupload.controller;

import com.example.fileupload.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 ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        String fileName = fileStorageService.storeFile(file);
        return ResponseEntity.ok("File uploaded successfully: " + fileName);
    }

    @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 upload and download REST endpoints.
  • The uploadFile method handles file upload requests.
  • The downloadFile method handles file download requests.

3.2 Create the FileUploadApplication Class

Ensure the FileUploadApplication class is present in the src/main/java/com/example/fileupload directory:

package com.example.fileupload;

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

@SpringBootApplication
public class FileUploadApplication {

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

Step 4: Running the Application

  1. Open the FileUploadApplication class in the src/main/java/com/example/fileupload 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 Spring Boot application to handle file uploads and downloads. We implemented a file storage service and created REST endpoints to upload and download files. This setup provides a solid foundation for developing more complex file management systems.


Comments