[Tistory] AWS | S3 를 이용한 파일 업로드 기능 with Kotlin, swagger

원글 페이지 : 바로가기

aws 버킷생성 1. 버킷 만들기 선택 2. AWS지역과 버킷 이름을 입력 3. 객체 소유권을 ACL 비활성화됨으로 되어있는데 ACL 활성화됨으로 변경 (유의사항 꼭 확인 – 불이익시 내 책임 아님!!) 4. 아래 항목에 대해 체크를 해제하여 외부의 모든 사용자들이 접근 가능한 Public 객체 생성이 가능합니다. Public Access 설정을 원하는 버킷 선택 [권한] -> [퍼블릭 액세스 차단(버킷 설정)] 에서 [편집] 아래 항목에 대한 체크 해제 후 저장 (유의사항 꼭 확인 – 키 노출시 돈 털릴 수 있음 – 불이익시 내 책임 아님!! ) aws 설정 참고: https://support.bespinglobal.com/ko/support/solutions/articles/73000544767–aws-amazon-s3-bucket-public-access-%EC%84%A4%EC%A0%95 5. 버킷 이름 클릭 6. 폴더만들기 7. 폴더이름 짓기 8. 폴더 확인 AWS 세팅 1. build.gradle에 의존성 추가 implementation(“org.springframework.cloud:spring-cloud-starter-aws:2.0.1.RELEASE”) 2. aws.yml 추가 (이 파일은 반드시!! github에 노출되지 않도록 조심!! 카드에서 돈 털림 주의) accessKey: AWS IAM의 access-key
secretKey: AWS IAM의 secret-key
bucket: 버킷 이름
dir: 폴더이름/
region: ap-northeast-2 3. AwsConfig 추가 package com.teamsparta.bunnies.infra.aws

import com.amazonaws.auth.AWSCredentials
import com.amazonaws.auth.AWSStaticCredentialsProvider
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.PropertySource

@PropertySource(“classpath:aws.yml”)
@Configuration
class AwsConfig {
@Value(“\${accessKey}”)
private val accessKey: String? = null

@Value(“\${secretKey}”)
private val secretKey: String? = null

@Value(“\${region}”)
private val region: String? = null

@Bean
fun amazonS3Client(): AmazonS3Client {
val awsCredentials: AWSCredentials = BasicAWSCredentials(accessKey, secretKey)
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(AWSStaticCredentialsProvider(awsCredentials))
.build() as AmazonS3Client
}
} 4. S3Service 생성 package com.teamsparta.bunnies.infra.aws

import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model.CannedAccessControlList
import com.amazonaws.services.s3.model.ObjectMetadata
import com.amazonaws.services.s3.model.PutObjectRequest
import com.amazonaws.util.IOUtils
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.PropertySource
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import java.io.ByteArrayInputStream
import java.io.IOException
import java.util.*

@PropertySource(“classpath:aws.yml”)
@Service
class S3Service(
private val s3Client: AmazonS3Client
) {

@Value(“\${bucket}”)
lateinit var bucket: String

@Value(“\${dir}”)
lateinit var dir: String

@Throws(IOException::class)
fun upload(file: MultipartFile): String {
val fileName = UUID.randomUUID().toString() + “-” + file.originalFilename
val objMeta = ObjectMetadata()

val bytes = IOUtils.toByteArray(file.inputStream)
objMeta.contentLength = bytes.size.toLong()

val byteArrayIs = ByteArrayInputStream(bytes)

s3Client.putObject(
PutObjectRequest(bucket, dir + fileName, byteArrayIs, objMeta)
.withCannedAcl(CannedAccessControlList.PublicRead))

return s3Client.getUrl(bucket, dir + fileName).toString()
}

} 5. ImageController 생성 package com.teamsparta.bunnies.domain.image.controller

import com.teamsparta.bunnies.domain.image.dto.UploadImageResponse
import com.teamsparta.bunnies.infra.aws.S3Service
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile

@Tag(name = “image”, description = “이미지 관리 API”)
@RequestMapping(“/api/images”)
@RestController
class ImageController(
private val s3Service: S3Service
) {
@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
fun uploadImage(@RequestParam(“image”) multipartFile: MultipartFile): ResponseEntity {
return ResponseEntity
.ok(UploadImageResponse(url=s3Service.upload(multipartFile)))

}
} 6. UploadImageResponse 생성 package com.teamsparta.bunnies.domain.image.dto

data class UploadImageResponse(
val url: String
) 7. 키 노출 방지를 위해서 aws.yml 파일이 github에 올라가는걸 막기 위해 gitignore 파일에 aws.yml을 추가해준다 Swagger테스트 1. 파일 선택 후 Excute 한다. 2. 이미지 URL 반환함 3. 반환하는 URL을 크롬 주소창에 복사해서 붙여 넣으면 4. 해당 이미지를 다운 받을 수 있는 창이 보여진다. 참고: https://devlog-wjdrbs96.tistory.com/403 참고: https://velog.io/@s2moon98/S3%EC%97%90-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5%ED%95%98%EB%8A%94-%EC%84%9C%EB%B2%84%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EC%9E%90

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다