우테코 내부에서는 이미 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
복사
•
ResourceLoader와 SimpleStorageProtocolResolver를 사용하여 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
복사