S3에 이미지 저장
이전 글에서 S3 버킷을 만들어두었다.
이번 글에서는 S3에 이미지를 저장하는 방법을 정리해보려 한다.
최근 알게 된 Presigned URL 방식으로 프론트에서 이미지를 저장하는 방식도 있지만
이번 글에서는 프론트에서 MultipartFile 형태로 이미지를 받아서 저장하는 방식으로 해보았다.
Presigned URL 방식은 추후 따로 글 쓸듯.
사용 기술
- Spring Boot 3.2.4 / gradle-kotlin
- Java 17
- Aws SDK
1. Aws SDK 관련 설정
Aws SDK 의존성 추가
// build.gradle.kts
implementation(platform("software.amazon.awssdk:bom:2.25.35"))
implementation("software.amazon.awssdk:s3")
Aws SDK를 사용하는 방법은 두가지가 있다.
- BOM을 이용한 개별 의존성 추가 방법
- SDK 전체 추가
본인은 어차피 S3만 쓸것 같기 때문에 S3만 추가하였다.
application.yml 설정
액세스 키, 시크릿 키를 확인하는 방법은 이 글을 확인하자.
이전 글의 마지막에서 만든 액세스 포인트를 활용한다.
aws:
access-key: # AWS 액세스 키
secret-key: # AWS 시크릿 키
s3-access-point: # S3 액세스 포인트
AwsConfig 설정
이미지 업로드에 사용할 S3Client를 빈 등록해준다.
@RequiredArgsConstructor
@ConfigurationProperties(prefix = "aws")
public class AwsConfig {
private final String accessKey;
private final String secretKey;
private final String s3AccessPoint;
public String getS3AccessPoint() {
return s3AccessPoint;
}
@Bean
public S3Client s3Client() {
return S3Client.builder()
.credentialsProvider(getAwsBasicCredentials())
.region(Region.AP_NORTHEAST_2)
.build();
}
private StaticCredentialsProvider getAwsBasicCredentials() {
return StaticCredentialsProvider.create(
AwsBasicCredentials.create(accessKey, secretKey)
);
}
}
2. S3Client를 이용하여 이미지 업로드
ImageController
@RequestParam이나 @RequestPart 애노테이션을 이용해서 MultipartFile을 받는다.
@ModelAttribute로 객체로 받아도 무관하다.
@RestController
@RequiredArgsConstructor
public class ImageController {
private final ImageService imageService;
@PostMapping("/upload")
public String uploadFile(@RequestPart MultipartFile file) throws IOException {
imageService.upload(file);
return "이미지 저장 성공";
}
}
ImageService
컨트롤러에서 받은 MultipartFile을 서비스 레이어에서 처리한다.
S3Client.putObject() 메서드가 받는 인자는 PutObjectRequest, RequestBody 두 개이다.아래처럼 MultipartFile의 inputStream으로 RequestBody를 만들어주면 되고key에는 S3에 저장할 파일 이름을 넣어주면 된다.PutObject라는 이름처럼 같은 이름의 파일이라면 덮어 씌우므로 여러 사람이 이미지를 올린다면 UUID 형태로 저장하는게 좋다.
@Service
@RequiredArgsConstructor
public class ImageService {
private final S3Client s3Client;
private final AwsConfig awsConfig;
public void upload(MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
RequestBody requestBody = RequestBody.fromInputStream(file.getInputStream(), file.getSize());
s3Client.putObject(builder -> builder
.bucket(awsConfig.getS3AccessPoint())
.key(fileName) // S3에 저장할 파일명
, requestBody);
}
}
3. 결과 확인
PostMan 으로 이미지를 저장해보자.
MultipartFile 형태로 데이터를 받으므로 form-data로 요청을 보내야한다.
S3 버켓을 확인하면 이미지도 제대로 저장됨을 알 수 있다.
'API 만들어 보기 > 이미지 저장' 카테고리의 다른 글
이미지 저장 3: 프리사인 URL 사용 (0) | 2024.04.18 |
---|---|
이미지 저장 1: S3 이미지 저장소 생성 (0) | 2024.04.12 |