AWS S3는 객체 스토리지 서비스로, 데이터를 "버킷(bucket)"에 저장하는 방식입니다. 각 버킷은 사용자가 지정한 이름과 권한을 가지며, 내부에 저장된 데이터는 객체(object)로 관리됩니다. S3는 확장성, 보안, 높은 가용성을 제공하여 다양한 애플리케이션에서 데이터 저장소로 활용됩니다.
버킷(Bucket): 파일을 저장하는 기본 단위로, 하나의 버킷 안에 수많은 파일(객체)을 저장할 수 있습니다.
객체(Object): 파일 그 자체로, 메타데이터와 데이터로 이루어져 있습니다.
ACL(Access Control List): 각 객체와 버킷에 대해 접근 권한을 설정할 수 있는 기능입니다.
버전 관리: S3는 파일의 여러 버전을 관리할 수 있습니다.
라이프사이클: 파일을 자동으로 아카이브하거나 삭제할 수 있는 규칙을 설정할 수 있습니다.
Spring Boot와 S3를 연동하기 위해서는 AWS SDK를 사용해야 합니다. Spring Boot는 다양한 AWS 서비스를 쉽게 연동할 수 있도록 라이브러리 및 설정을 지원합니다.
필수 설정 및 라이브러리 추가
implementation 'software.amazon.awssdk:s3:2.20.0'
implementation 'org.springframework.boot:spring-boot-starter-web'
AWS 자격 증명 설정
AWS 자격 증명을 설정해야 S3와 통신할 수 있습니다. 기본적으로, ~/.aws/credentials 파일에 자격 증명을 설정할 수 있습니다.
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
S3 클라이언트 설정
Spring Boot 애플리케이션에서 S3 클라이언트를 설정하는 방법입니다.
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class S3Config {
@Bean
public S3Client s3Client() {
return S3Client.builder()
.region(Region.AP_NORTHEAST_2) // 서울 리전
.credentialsProvider(ProfileCredentialsProvider.create())
.build();
}
}
S3 파일 업로드 및 다운로드 서비스 구현
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@Service
public class S3Service {
private final S3Client s3Client;
private final String bucketName = "your-bucket-name";
public S3Service(S3Client s3Client) {
this.s3Client = s3Client;
}
public void uploadFile(MultipartFile file) throws IOException {
Path tempFile = Paths.get(System.getProperty("java.io.tmpdir"), file.getOriginalFilename());
file.transferTo(tempFile.toFile());
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(file.getOriginalFilename())
.build();
s3Client.putObject(putObjectRequest, tempFile);
}
}
+ 파일 다운로드 서비스
S3에서 파일을 다운로드하는 서비스도 쉽게 구현할 수 있습니다.
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import software.amazon.awssdk.services.s3.S3Client;
@Service
public class S3DownloadService {
private final S3Client s3Client;
private final String bucketName = "your-bucket-name";
public S3DownloadService(S3Client s3Client) {
this.s3Client = s3Client;
}
public InputStream downloadFile(String fileName) {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
return s3Client.getObject(getObjectRequest);
}
}
컨트롤러 구현
파일을 업로드하고 다운로드할 수 있는 API를 제공합니다.
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.ResponseEntity;
import java.io.IOException;
@RestController
@RequestMapping("/s3")
public class S3Controller {
private final S3Service s3Service;
private final S3DownloadService s3DownloadService;
public S3Controller(S3Service s3Service, S3DownloadService s3DownloadService) {
this.s3Service = s3Service;
this.s3DownloadService = s3DownloadService;
}
@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
try {
s3Service.uploadFile(file);
return ResponseEntity.ok("File uploaded successfully!");
} catch (IOException e) {
return ResponseEntity.status(500).body("File upload failed!");
}
}
@GetMapping("/download/{fileName}")
public ResponseEntity<InputStreamResource> downloadFile(@PathVariable String fileName) {
InputStream fileStream = s3DownloadService.downloadFile(fileName);
return ResponseEntity.ok(new InputStreamResource(fileStream));
}
}
3. 보안 및 최적화
S3와의 연동에서 보안과 비용 최적화를 고려하는 것은 매우 중요합니다.
IAM 역할 및 정책: 특정 리소스에 대한 권한을 제한하는 정책을 적용해야 합니다. IAM 역할을 사용하여 S3 버킷에 대한 액세스를 최소화하는 것이 좋습니다.
S3 라이프사이클 정책: S3에 저장된 데이터를 비용 효율적으로 관리하기 위해, 데이터를 일정 기간 후 아카이브하거나 삭제하는 라이프사이클 정책을 설정할 수 있습니다.
암호화: S3에 저장된 데이터를 암호화하는 것이 좋습니다. AWS에서 제공하는 서버 측 암호화(SSE)를 활용하면 안전하게 데이터를 보호할 수 있습니다.