//
Search
🦈

Spring Cloud AWS Starter vs. AWS Java SDK For Amazon S3

블로그로 정리해 올린 글입니다
작성자
우테코 내부에서는 이미 EC2의 IAM Role을 설정해두었기에 키를 따로 설정해주지 않아도 사용 가능

Spring Cloud AWS Starter

//의존성 주입 implementation 'software.amazon.awssdk:s3:2.20.0
Java
복사
public void uploadFile(String bucketName, String fileName, byte[] data) throws IOException { String s3Url =bucketName + "/" + fileName; Resource resource = resourceLoader.getResource(s3Url); Files.write(Paths.get(resource.getURI()), data); } public byte[] downloadFile(String bucketName, String fileName) throws IOException { String s3Url = bucketName + "/" + fileName; Resource resource = resourceLoader.getResource(s3Url); return Files.readAllBytes(Paths.get(resource.getURI())); }
Java
복사
ResourceLoaderSimpleStorageProtocolResolver를 사용하여 S3 객체를 Spring의 Resource로 취급
설정이 상대적으로 간단, Spring의 Scheduler, AOP와 쉬운 결합
단, Spring 외부에선 사용이 어렵다.
Release된 지 오래되어 최신 기능을 사용할 수 없음

AWS Java SDK For Amazon S3

private S3Client s3Client; public S3SdkService(String accessKey, String secretKey, Region region) { this.s3Client = S3Client.builder() .region(region) .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey))) .build(); } public void uploadFile(String bucketName, String keyName, String filePath) { PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket(bucketName) .key(keyName) .build(); s3Client.putObject(putObjectRequest, Paths.get(filePath)); } public void downloadFile(String bucketName, String keyName, String downloadPath) { GetObjectRequest getObjectRequest = GetObjectRequest.builder() .bucket(bucketName) .key(keyName) .build(); s3Client.getObject(getObjectRequest, Paths.get(downloadPath)); } public void deleteFile(String bucketName, String keyName,) { DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder() .bucket(bucketName) .key(keyName) .build(); }
Java
복사
S3의 모든 API에 접근 가능
버킷 생성, 버킷 목록 조회, 버킷 삭제
객체 업로드, 객체 다운로드, 객체 삭제, 객체 목록 조회
객체 버전 관리, 객체 복제
객체 ACL 설정, 버킷 정책 설정
Multipart 업로드
Spring과 연동하는 것이 아닌 Java 애플리케이션 내에서 S3 기능 제어 가능(S3Client)

총대마켓이 작성한 코드

package com.zzang.chongdae.storage.service; import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.zzang.chongdae.global.exception.MarketException; import com.zzang.chongdae.storage.exception.StorageErrorCode; import java.io.IOException; import java.io.InputStream; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.util.UriComponentsBuilder; @RequiredArgsConstructor @Service public class StorageService { private final AmazonS3 s3Client; @Value("${amazon.s3.bucket}") private String bucketName; @Value("${amazon.cloudfront.redirectUrl}") private String redirectUrl; public String uploadFile(MultipartFile file, String path) { try { String objectKey = path + UUID.randomUUID(); InputStream inputStream = file.getInputStream(); ObjectMetadata metadata = createMetadata(file); PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, inputStream, metadata); s3Client.putObject(putObjectRequest); return createUri(objectKey); } catch (IOException e) { throw new MarketException(StorageErrorCode.INVALID_FILE); } catch (SdkClientException e) { throw new MarketException(StorageErrorCode.STORAGE_SERVER_FAIL); } } private ObjectMetadata createMetadata(MultipartFile file) { ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(file.getSize()); metadata.setContentType(file.getContentType()); return metadata; } private String createUri(String objectKey) { return UriComponentsBuilder.newInstance() .scheme("https") .host(redirectUrl) .path("/" + objectKey) .build(false) .toString(); } }
Java
복사