1. 이미지 저장 방식 지정
- 이미지를 저장하기 위해서는 이미지의 바이트를 저장해야한다.
- 그런데, 우리 프로젝트에서는 해당 데이터를 모두 서버에 저장할 경우 → 서버 용량 엄청 커야할 듯..
- 따라서 외부 스토리지 서비스를 활용하여 이미지를 저장하고, 우리 DB에는 해당 이미지가 저장된 스토리지의 URL를 저장하여 다시 불러올 수 있도록 하기로 하였다.
- 그 중에서도 우리 서버가 AWS EC2인 점을 감안하여 AWS S3 스토리지 서비스를 활용하기로 하였다.
2. S3 버킷 생성 및 프로젝트와 연동
- AWS S3 버킷은 프로그래밍 코드를 통해 접근할 수 있도록 access key와 secret을 생성하여 활용할 수 있도록한다.
- 해당 정보들은 민감정보이므로 yml 파일에서 관리할 수 있도록 한다.
- 프로젝트에서 해당 버킷을 사용할 수 있도록
AmazonS3Client 를 스프링 빈으로 등록해준다.
@Configuration
public class S3Config {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3Client amazonS3Client() {
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client)AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
}
- 코드 설명:
- 여기서는 일단
AmazonS3Client 을 @Configuration + @Bean 방식으로 자동 빈 등록해주었다.
- 해당 빈생성을 위해 필요한 properties는 yml에 작성해두고,
@Value 방식으로 주입받았다.
- 근데
@Value 에 의존적이지 않고, properties를 주입받을 수 있도록 @ConfigurationProperties 를 활용하는 방식으로 변경해야겠다는 생각이 들었다.. 즉, 리팩토링 대상이다.
- 이유는
RelaxedBinding & 여러개의 값을 한번에 주입받는 @ConfigurationProperties 의 특성 때문이다.
- 더 유연하고, 간결한 코드가 필요하다!
- 결과:
- 어쨌든
AmazonS3Client 를 생성하였고, 앞으로 해당 객체를 통해 S3 버킷에 이미지를 저장하고 접근할 것이다.
3. 이미지 업로더 구현
- S3에 이미지를 저장하기 위해서는
amazonS3Client.putObject() 메서드를 사용하였다.
- 이때,
amazonS3Client.putObject() 메서드의 매개변수로는 PutObjectRequest 객체가 들어가야하고, 해당 객체의 생성자의 매개변수에는 S3버킷명, File 타입의 파일객체와 파일명이 들어간다.
- 여기서 이
File 타입의 파일 객체를 생성하기 위해서 서버에 일시적으로 File 객체를 생성하고, S3 버킷에 저장이 완료되면 해당 File을 삭제하도록 하였다.
- 그리고 S3 버킷에 이미지 저장 결과로는 해당 버킷의 URL을 반환하도록 하여 DB에 저장할 수 있도록 하였다.