aws s3 이미지 업로드
MultipartFile 업로드 방식
참조 : ( https://techblog.woowahan.com/11392/ , https://varjm.tistory.com/79 , https://growth-coder.tistory.com/114, https://chb2005.tistory.com/200 )
https://chb2005.tistory.com/200
클라이언트에서 첨부파일로 이미지를 업로드하면
스프링부트에서 이미지 파일을 MultipartFile 객체로 변환, S3 에 파일업로드,
클라이언트에 이미지 url 을 반환
aws s3 버킷 생성
IAM, 정책 설정
S3Service
더보기
package org.example.todolist.infra.aws
import com.amazonaws.services.s3.AmazonS3Client
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 imageUpload(file: MultipartFile): String { // 파일 업로드시 톰캣이 임시 디렉터리에 저장, MultipartFile 로 매핑
val fileName = UUID.randomUUID().toString() + "-" + file.originalFilename
val objMeta = ObjectMetadata() // MultipartFile 매핑 -> 메타데이터에 접근 가능
val bytes = IOUtils.toByteArray(file.inputStream) // multipartFile 내용 바이트 변환
objMeta.contentLength = bytes.size.toLong() // 업로드될 파일의 크기 설정
val byteArrayIs = ByteArrayInputStream(bytes) //
s3Client.putObject(
PutObjectRequest(bucket, dir + fileName, byteArrayIs, objMeta)
)
return s3Client.getUrl(bucket, dir + fileName).toString() // url 반환
}
}
AweConfig
더보기
package org.example.todolist.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
}
}
post 생성할 때 userprincipal 을 받아오는게 문제가 되는건지 접근을 다 열어놔도 아래와 같이 뜬다.
해결방법을 못찾아서 일단 이미지 업로드 메소드만 따로 빼서 userprincipal 안 받고 실행하면 정상적으로 s3 에 업로드가 된다.
.authorizeHttpRequests {
it.requestMatchers(
"/swagger-ui/**", "/v3/api-docs/**", "/posts","/auth/**", "/images/**"
).permitAll()
.anyRequest().authenticated()
}
게시글 업로드 할 때 이미지가 같이 업로드가 돼야 정상적인 업로드인데 어떻게 해결할 수 있을까...
postman 업로드 성공
@Operation(summary = "할 일 생성")
@PostMapping(
consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]
)
fun createPost(@AuthenticationPrincipal userPrincipal: UserPrincipal,
@RequestPart(required = false) multipartFile: MultipartFile?,
@Valid@RequestPart postRequest: PostRequest,
): ResponseEntity<Any> {
if (multipartFile == null || multipartFile.isEmpty) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("이미지를 넣어주세요")
}
val image = s3Service.imageUpload(multipartFile)
return ResponseEntity.status(HttpStatus.CREATED).body(postService.createdPost(userPrincipal, postRequest))
}
RequestPart("" => postman key
@RequestPart(required = false)
https://velog.io/@hellozin/RequestParamrequired-false-%EC%A3%BC%EC%9D%98%ED%95%A0-%EC%A0%90
'왕초보일지' 카테고리의 다른 글
240214 TIL | (0) | 2024.02.14 |
---|---|
240213 TIL | 테스트 코드 (0) | 2024.02.13 |
240207 TIL | ObjectMapper (0) | 2024.02.07 |
240206 TIL | (1) | 2024.02.06 |
240202 TIL | validation / spring aop / querydsl (0) | 2024.02.02 |