Spring Boot DigitalOcean Spaces: File Upload, List, Download, and Delete


To upload, list, download, and delete files using DigitalOcean Spaces (object storage), you can follow these steps with a Spring Boot application. DigitalOcean Spaces is compatible with the AWS S3 API, so you can use the AWS SDK to interact with it.

Steps:

  1. Create a DigitalOcean Space:

    • Log into your DigitalOcean account and create a new Space under the "Spaces" tab.
    • Note the Space's endpoint, access key, and secret key.
  2. Add Dependencies in pom.xml: Add the following dependencies for AWS SDK (which is compatible with DigitalOcean Spaces) in your pom.xml:

    <dependencies>
        <!-- AWS SDK for S3 (Compatible with DigitalOcean Spaces) -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <version>2.29.39</version>
        </dependency>
        <!-- Spring Boot starter web for REST API -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  3. Configuration for DigitalOcean Space: In your application.properties or application.yml, add your DigitalOcean Spaces credentials:

    do.space.access-key=your-access-key
    do.space.secret-key=your-secret-key
    do.space.endpoint=https://nyc3.digitaloceanspaces.com  # Use your region's endpoint
    do.space.bucket-name=your-space-name
  4. Service to Interact with DigitalOcean Spaces: Create a service class to handle file upload, download, list, and delete operations.

    import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
    import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.s3.S3Client;
    import software.amazon.awssdk.services.s3.model.*;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.List;
    
    @Service
    public class DigitalOceanSpaceService {
    
        @Value("${do.space.access-key}")
        private String accessKey;
    
        @Value("${do.space.secret-key}")
        private String secretKey;
    
        @Value("${do.space.endpoint}")
        private String endpoint;
    
        @Value("${do.space.bucket-name}")
        private String bucketName;
    
        private final S3Client s3Client;
    
        public DigitalOceanSpaceService() {
            AwsBasicCredentials awsCreds = AwsBasicCredentials.create(accessKey, secretKey);
            this.s3Client = S3Client.builder()
                    .region(Region.of("us-east-1"))  // Use your space's region
                    .endpointOverride(URI.create(endpoint))
                    .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                    .build();
        }
    
        // Upload file
        public String uploadFile(Path filePath) throws IOException {
            String fileName = filePath.getFileName().toString();
            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(fileName)
                    .build();
    
            s3Client.putObject(putObjectRequest, filePath);
            return fileName;
        }
    
        // List files in Space
        public ListObjectsV2Response listFiles() {
            ListObjectsV2Request listObjects = ListObjectsV2Request.builder()
                    .bucket(bucketName)
                    .build();
    
            return s3Client.listObjectsV2(listObjects);
        }
    
        // Download file
        public byte[] downloadFile(String fileName) {
            GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                    .bucket(bucketName)
                    .key(fileName)
                    .build();
    
            return s3Client.getObject(getObjectRequest).readAllBytes();
        }
    
        // Delete file
        public void deleteFile(String fileName) {
            DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
                    .bucket(bucketName)
                    .key(fileName)
                    .build();
    
            s3Client.deleteObject(deleteObjectRequest);
        }
    }
    
  5. Controller to Handle HTTP Requests: Create a REST controller to expose endpoints for uploading, listing, downloading, and deleting files.

    import org.springframework.beans.factory.annotation.Autowired;
    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.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    @RestController
    @RequestMapping("/files")
    public class FileController {
    
        @Autowired
        private DigitalOceanSpaceService spaceService;
    
        // Upload file
        @PostMapping("/upload")
        public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
            try {
                Path tempFile = Files.createTempFile(file.getOriginalFilename(), ".tmp");
                file.transferTo(tempFile);
    
                String fileName = spaceService.uploadFile(tempFile);
                return new ResponseEntity<>(fileName, HttpStatus.OK);
            } catch (IOException e) {
                return new ResponseEntity<>("File upload failed", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    
        // List files
        @GetMapping("/list")
        public ResponseEntity<?> listFiles() {
            return new ResponseEntity<>(spaceService.listFiles().contents(), HttpStatus.OK);
        }
    
        // Download file
        @GetMapping("/download/{fileName}")
        public ResponseEntity<byte[]> downloadFile(@PathVariable String fileName) {
            try {
                byte[] fileBytes = spaceService.downloadFile(fileName);
                return ResponseEntity.ok(fileBytes);
            } catch (Exception e) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
        }
    
        // Delete file
        @DeleteMapping("/delete/{fileName}")
        public ResponseEntity<String> deleteFile(@PathVariable String fileName) {
            try {
                spaceService.deleteFile(fileName);
                return new ResponseEntity<>("File deleted successfully", HttpStatus.OK);
            } catch (Exception e) {
                return new ResponseEntity<>("Failed to delete file", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    }
    
  6. Run Your Spring Boot Application: Start your Spring Boot application. You can now use the following endpoints:

    • Upload File: POST /files/upload with a multipart/form-data request body containing the file.
    • List Files: GET /files/list
    • Download File: GET /files/download/{fileName}
    • Delete File: DELETE /files/delete/{fileName}

Conclusion:

This setup uses the AWS SDK for S3 to interact with DigitalOcean Spaces. It allows you to upload, list, download, and delete files from your DigitalOcean Space using Spring Boot. Make sure to replace the access credentials, bucket name, and endpoint with your actual DigitalOcean Space settings.

Comments

Popular posts from this blog

Spring Boot OpenAI Integration: Step-by-Step Guide

Orchestration-Based Saga Architecture and Spring Boot Microservices Implementation Guide

Spring Boot 3 + Angular 15 + Material - Full Stack CRUD Application Example