CODE WITH SIBIN

Solving Real Problems with Real Code


Spring Boot 3 Google Cloud Storage Integration: Upload, Download, List & Delete Files

Modern applications often require a reliable way to store and manage files, and Google Cloud Storage (GCS) provides an excellent solution. It is scalable, dependable, and seamlessly integrates with cloud-based applications.

This guide will walk you through integrating Spring Boot 3 with Google Cloud Storage, enabling your application to:

  • Upload files to GCS
  • List files within a GCS bucket
  • Download files from GCS
  • Delete files from GCS

We'll build a RESTful API to manage file operations using Spring Boot and Google Cloud Storage. You will learn how to set up the project, handle authentication, implement core features, and test your APIs for a production-ready solution.

Benefits of Using Google Cloud Storage

Google Cloud Storage is a preferred choice for many businesses due to its numerous advantages:

  • Global Scalability: Store and access files from anywhere in the world.
  • Security & Access Control: Manage permissions effectively using IAM roles.
  • Performance & Reliability: Ensures high availability with automatic redundancy.
  • Multiple Storage Classes: Optimize costs with Standard, Nearline, Coldline, and Archive storage.
  • Seamless Integration: Works well with Google AI, BigQuery, Kubernetes, and other Google services.

Common Use Cases

By combining Google Cloud Storage with Spring Boot, you can create solutions for a variety of applications:

  • Web Applications: Upload and store user files, images, and documents.
  • Mobile Apps: Sync user-generated content efficiently.
  • Media Streaming: Store and serve videos, music, and large files.
  • Document Processing: Manage PDFs and leverage AI-based text extraction.

What You’ll Learn

This guide provides step-by-step instructions to integrate Google Cloud Storage with a Spring Boot 3 application. Key topics include:

  • Project Setup: Adding necessary dependencies and configuring pom.xml.
  • Google Cloud Authentication: Setting up secure access credentials.
  • File Storage Service: Implementing core features like uploading, listing, downloading, and deleting files.
  • REST Controller: Creating APIs to manage file operations.
  • Testing with Postman: Verifying API functionality.
  • Unit Testing: Writing tests to ensure reliability and correctness.

By the end of this guide, you will have a fully functional Spring Boot application that integrates efficiently with Google Cloud Storage for managing file operations.

1. Project Setup

1.1 Add Dependencies

Ensure your pom.xml includes:

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Google Cloud Storage Starter -->
    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>spring-cloud-gcp-starter-storage</artifactId>
    </dependency>

    <!-- Spring Boot Starter Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2. Configure Google Cloud Authentication

Before using GCS, you need to authenticate with Google Cloud.

2.1 Create a Service Account

🔹 Step 1: Sign in to Google Cloud Console

  1. Open your web browser and go to the Google Cloud Console.
  2. Sign in using your Google account (ensure you have the necessary permissions to create service accounts).
  3. If you haven't already created a Google Cloud project, create one by clicking the Select a Project dropdown in the top bar and choosing New Project.

🔹 Step 2: Navigate to the Service Accounts Page

  1. In the Google Cloud Console, locate the left-side menu.
  2. Click on IAM & AdminService Accounts.
  3. This will take you to the Service Accounts dashboard, where you can create and manage service accounts for your project.

🔹 Step 3: Create a New Service Account

  1. Click on the + CREATE SERVICE ACCOUNT button at the top.
  2. Enter a name for your service account (e.g., spring-boot-gcs-service).
  3. Optionally, provide a description to explain its purpose.
  4. Click Create and Continue.

🔹 Step 4: Assign Permissions to the Service Account

  1. In the Grant this service account access to project step, you need to assign the correct permissions.
  2. Under Select a role, search for Storage Admin.
  3. Select the Storage Admin role, which provides full control over Google Cloud Storage, including uploading, listing, downloading, and deleting files.
  4. Click Continue.

🔹 Step 5: Generate a JSON Key for Authentication

  1. After creating the service account, navigate to the Keys tab.
  2. Click Add KeyCreate New Key.
  3. Choose JSON as the key format and click Create.
  4. Your browser will download a JSON file containing the credentials needed to authenticate your Spring Boot application with Google Cloud Storage.
  5. Store this file securely – Do not share it or commit it to version control (e.g., GitHub).

2.2 Set Up Credentials

Place the JSON key in your project root or a secure location.

Then, in your application.properties or application.yml, configure:

spring.cloud.gcp.storage.credentials.location=file:/path-to-your-service-account-key.json
spring.cloud.gcp.storage.bucket=your-gcs-bucket-name

Or using application.yml:

spring:
  cloud:
    gcp:
      storage:
        credentials:
          location: file:/path-to-your-service-account-key.json
        bucket: your-gcs-bucket-name

3. Implement File Storage Service

Create a service to handle file operations.

3.1 FileStorageService

package com.example.demo.service;

import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@Service
public class FileStorageService {

    private final Storage storage;
    
    @Value("${spring.cloud.gcp.storage.bucket}")
    private String bucketName;

    public FileStorageService() {
        this.storage = StorageOptions.getDefaultInstance().getService();
    }

    // Upload file
    public String uploadFile(MultipartFile file) throws IOException {
        BlobId blobId = BlobId.of(bucketName, file.getOriginalFilename());
        BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
        storage.create(blobInfo, file.getBytes());

        return String.format("File %s uploaded successfully", file.getOriginalFilename());
    }

    // List files
    public List<String> listFiles() {
        return StreamSupport.stream(storage.list(bucketName).iterateAll().spliterator(), false)
                .map(Blob::getName)
                .collect(Collectors.toList());
    }

    // Download file
    public byte[] downloadFile(String fileName) {
        Blob blob = storage.get(BlobId.of(bucketName, fileName));
        return blob.getContent();
    }

    // Delete file
    public String deleteFile(String fileName) {
        boolean deleted = storage.delete(BlobId.of(bucketName, fileName));
        return deleted ? "File deleted successfully" : "File not found";
    }
}

4. Create REST Controller

Now, expose REST APIs to interact with Google Cloud Storage.

package com.example.demo.controller;

import com.example.demo.service.FileStorageService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

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

    private final FileStorageService fileStorageService;

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

    // Upload file
    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String response = fileStorageService.uploadFile(file);
            return ResponseEntity.ok(response);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed");
        }
    }

    // List files
    @GetMapping("/list")
    public ResponseEntity<List<String>> listFiles() {
        return ResponseEntity.ok(fileStorageService.listFiles());
    }

    // Download file
    @GetMapping("/download/{fileName}")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String fileName) {
        byte[] fileContent = fileStorageService.downloadFile(fileName);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
                .body(fileContent);
    }

    // Delete file
    @DeleteMapping("/delete/{fileName}")
    public ResponseEntity<String> deleteFile(@PathVariable String fileName) {
        return ResponseEntity.ok(fileStorageService.deleteFile(fileName));
    }
}

5. Testing the APIs with Postman

5.1 Upload File

  • Method: POST
  • URL: http://localhost:8080/api/files/upload
  • Body: Form-data with file as key and file as value.

5.2 List Files

  • Method: GET
  • URL: http://localhost:8080/api/files/list

5.3 Download File

  • Method: GET
  • URL: http://localhost:8080/api/files/download/{fileName}
  • Response: File content as binary.

5.4 Delete File

  • Method: DELETE
  • URL: http://localhost:8080/api/files/delete/{fileName}

6. Unit Testing

Create unit tests for the service.

package com.example.demo.service;

import com.google.cloud.storage.Storage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class FileStorageServiceTest {

    @Mock
    private Storage storage;

    @Mock
    private MultipartFile file;

    @InjectMocks
    private FileStorageService fileStorageService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    void uploadFile() throws IOException {
        when(file.getOriginalFilename()).thenReturn("test.txt");
        when(file.getBytes()).thenReturn("Test content".getBytes());

        assertDoesNotThrow(() -> fileStorageService.uploadFile(file));
    }

    @Test
    void listFiles() {
        when(storage.list(anyString())).thenReturn(null);
        assertEquals(Collections.emptyList(), fileStorageService.listFiles());
    }
}

7. Run the Application

Start your Spring Boot app:

mvn spring-boot:run

Your Google Cloud Storage API is now ready to handle file operations!

☁️ Spring Boot 3 Google Cloud Storage Integration

Upload, download, list, and delete files seamlessly using Spring Boot and Google Cloud Storage.

📂 Clone on GitHub

Leave a Reply

Your email address will not be published. Required fields are marked *