게시글에 이미지를 업로드 할 수 있는 기능이 필요했다
그래서 이미지를 저장할 수 있는 데이터베이스와 업로드한 이미지를 게시물에서 보여주기 위한 URL을 가져올 수 있어야했다
이를 구현하기 위해 두 가지 후보가 있었는데 첫 번째가 일반 서버를 이용하는 것이고 두 번째가 Amazon에서 서비스 하는 S3 버킷을 이용하는 것이었다
우리는 S3를 사용하기로 결정했다
AWS를 제대로 써본적이 없기 때문에 힘들 수 있겠다고 생각했지만 여러 블로그들을 참고하여 생각보다 수월하게 진행되었다
S3(Simple Storage Service)는 AWS에서 제공하는 인터넷 스토리지 서비스이다
S3 버킷 생성 후 기본 설정을 해주면 이제 스프링 프로젝트를 수정해줘야한다
implementation("io.awspring.cloud:spring-cloud-starter-aws:2.3.1")
Resource 패키지 우클릭 -> New -> Resource Bundle 클릭 후
이름을 application-s3로 하여 생성해준다
# AWS Account Credentials
cloud.aws.credentials.accessKey=
cloud.aws.credentials.secretKey=
# AWS S3 bucket Info
cloud.aws.s3.bucket=
cloud.aws.region.static=ap-northeast-2
cloud.aws.stack.auto=
그리고 위의 양식대로 파일을 수정해준다
@Configuration
class S3Config {
@Value("\${cloud.aws.credentials.accessKey}")
private lateinit var accesskey: String
@Value("\${cloud.aws.credentials.secretKey}")
private lateinit var secretKey: String
@Value("\${cloud.aws.region.static}")
private lateinit var region:String
@Bean
fun amazonS3Client(): AmazonS3Client {
val basicAWSCredentials: BasicAWSCredentials = BasicAWSCredentials(accesskey,secretKey)
return AmazonS3ClientBuilder
.standard()
.withRegion(region)
.withCredentials(AWSStaticCredentialsProvider(basicAWSCredentials))
.build()
as AmazonS3Client
}
}
application-s3/properties에 작성한 AccessKey 등의 값들을 읽어와서 AmazonS3Client 객체를 생성할 때 의존성을 주입 해준다
@Service
class AwsS3Service(
private val amazonS3Client: AmazonS3Client,
private val uploadUtils: UploadUtils) {
@Value("\${cloud.aws.s3.bucket}")
private lateinit var bucket:String
//파일을 aws 보내고 url 받기
fun uploadFiles(files:List<MultipartFile>): List<String> {
var imageUrls = ArrayList<String>()
for (file in files) {
val originalFileName: String? = file.originalFilename
if(uploadUtils.isNotImageFile(originalFileName as String))
throw IllegalArgumentException("png, jpeg, jpg에 해당하는 파일만 업로드할 수 있습니다.");
val objectMetadata = ObjectMetadata()
objectMetadata.setContentLength(file.getSize())
objectMetadata.setContentType(file.getContentType())
try {
val inputStream:InputStream = file.inputStream
amazonS3Client.putObject(bucket,originalFileName, inputStream,objectMetadata);
val uploadFileUrl = amazonS3Client.getUrl(bucket, originalFileName).toString();
imageUrls.add(uploadFileUrl)
}catch (e: IOException) {
e.printStackTrace();
}
}
return imageUrls
}
//URL을 DB에 저장 후 DTO로 반환하기
@Transactional
fun storeUrls(userId:Int, imageUrls: List<String>, files: List<MultipartFile>): ArrayList<UploadLogDTO> {
val dtoList = ArrayList<UploadLogDTO>()
for ((index, file) in files.withIndex()) {
if(uploadUtils.isNotImageFile(file.originalFilename as String))
throw IllegalArgumentException("png, jpeg, jpg에 해당하는 파일만 업로드할 수 있습니다.");
val storeUrlDto = UploadLogDTO(
user_id = userId,
file_size = file.size.toInt(),
upload_date = LocalDateTime.now(),
url = imageUrls[index]
)
dtoList.add(storeUrlDto)
/* TODO Mapper 이용해 db 저장 하기 */
}
return dtoList
}
}
uploadUtils 파일에 대한 내용은 어디에 있을까요 ?