How to Download Large Files from S3 Bucket in Java/Spring Boot

To download files from S3, you will need to add the AWS Java SDK For Amazon S3 dependency to your application. Here is the Maven repository for Amazon S3 SDK for Java.


Gradle Dependency

Add the following dependency to the build.gradle file:


implementation group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.1009'

Maven Dependency

Add the following dependency to the pom.xml file:


    

Example Code

Here is a Java/Spring Boot example code for downloading large files from Amazon S3:

Service Class

amazon-s3-sample/src/main/java/com/sample/s3/service/S3DownloadExampleService.java

package com.sample.s3.service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@service
public class S3DownloadExampleService {

  private String bucketName = "my-test-bucket";
  private String folderName = "myfolder/images/";

  @Autowired
  private AmazonS3 s3Client;

  public void downloadFileFromS3(String fileName, HttpServletResponse
     response) {

    String fileNameWithExtension = fileName + ".pdf";
    S3Object s3Object = null;
    String fileLocationKey = folderName + fileNameWithExtension;

    InputStream is = null;
    OutputStream os = null;

    /*Retrieve file as object from S3*/
    s3Object = s3Client.getObject(new GetObjectRequest(bucketName,
       fileLocationKey));

    is = s3Object.getObjectContent();

    long fileLength = s3Object.getObjectMetadata().getContentLength();

    try {
       /*Send file direct back in response*/
       os = response.getOutputStream();
       response.setContentLength((int) fileLength);
       response.setHeader("Content-Disposition", "attachment; filename = " 
       + fileNameWithExtension);

       final String bufSize = "2048";

       final byte[] buffer = new byte[Integer.parseInt(bufSize)];
       int len = is.read(buffer, 0, buffer.length);
       
       while (len != -1) {
         os.write(buffer, 0, len);
         len = is.read(buffer, 0, buffer.length);
       }

    } catch (IOException e) {
      e.printStackTrace();
    } finally {
       try {
         if(s3Object != null) {
             s3Object.close();
          }
         
          if(is != null {)
             is.close();
          }

          if(os != null) {
             os.close();
          }

          if (response != null) {
             response.getOutputStream().close();
          }

    } catch (IOException ioException) {
      ioException.printStackTrace();
    }
   }
  }

}
 

Web Controller

amazon-s3-sample/src/main/java/com/sample/s3/controller/ S3FileDownloadController.java

    package com.sample.s3.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import com.example.s3.service.S3DownloadExampleService;

@RestController
@RequestMapping(value = "/api/files")
public class S3FileDownloadController {

  @Autowired
  private S3DownloadExampleService s3DownloadExampleService;

  @GetMapping(value = "/{filemane}/download")
  public void downloadFile(@PathVariable(name="filename",
   required=true) String filename) {

     s3downloadExampleService.downloadFileFromS3(filename);
  }

}