ํ”„๋กœ์ ํŠธ/NolGoat

๋ณด์•ˆ ์ทจ์•ฝ์  ํ•ด๊ฒฐ์„ ์œ„ํ•œ AWS S3 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ณ€๊ฒฝ

yongh๐Ÿ™‚ 2024. 12. 7. 23:04

๊ฐœ์š”

ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ์‹œ, ์ง€์†์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€์˜ ์›์ธ์„ ํ™•์ธํ•œ ๊ฒฐ๊ณผ, ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ org.springframework.cloud:spring-cloud-starter-aws ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ณด์•ˆ ์ทจ์•ฝ์ ์œผ๋กœ ์ธํ•ด 2021๋…„ 2์›” ์ดํ›„ Maven Repository์—์„œ ๋” ์ด์ƒ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์›์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
build.gradle์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์˜์กด์„ฑ์— ์ทจ์•ฝ์ ์ด ์žˆ๋‹ค๋Š” ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

 

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ณ€๊ฒฝ

ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด org.springframework.cloud:spring-cloud-starter-aws ๋Œ€์‹  io.awspring.cloud:spring-cloud-aws-starter-s3:3.0.0 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. 

implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3:3.0.0'

 

  • ์„ค์ • ํŒŒ์ผ(S3Config.java) ์‚ญ์ œ

Spring Cloud AWS S3๋Š” AWS์—์„œ ์ œ๊ณตํ•˜๋Š” Java SDK์™€ ๋‹ฌ๋ฆฌ, ๋ณ„๋„์˜ ์„ค์ • ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. CredentialsProviderAutoConfiguration ํด๋ž˜์Šค๊ฐ€ application.yml์— ๋“ฑ๋ก๋œ access-key์™€ secret-key๋ฅผ ์ž๋™์œผ๋กœ ์ฝ์–ด Credential ๊ด€๋ จ Provider ๊ฐ์ฒด๋“ค์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด AWS ์„œ๋น„์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
(์ด ๊ณผ์ •์€ ๋‚ด๋ถ€์ ์œผ๋กœ software.amazon.awssdk.services.s3 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.)

 

  • application.yml ์„ค์ •

๊ธฐ์กด ์„ค์ •์—์„œ spring ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค.

spring:
  cloud:
    aws:
      s3:
        bucket: ${bucket}
      credentials:
        access-key: ${accessKey}
        secret-key: ${secretKey}
      region:
        static: ${awsRegion}
        auto: false
      stack:
        auto: false

 

์ฝ”๋“œ ์ˆ˜์ •

AmazonS3 ๋Œ€์‹  S3Template์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

private final S3Template s3Template;

@Value("${spring.cloud.aws.s3.bucket}")
private String bucket;
public String saveFile(MultipartFile multipartFile) {
    String originalFilename = multipartFile.getOriginalFilename();
    String fileName = generateFileName(Objects.requireNonNull(originalFilename));

    String imageUrl;
    try {
        S3Resource s3Resource = s3Template.upload(
                bucket,
                fileName,
                multipartFile.getInputStream(),
                ObjectMetadata.builder()
                        .contentType(multipartFile.getContentType())
                        .build()
        );
        imageUrl = s3Resource.getURL().toString();
    } catch (IOException e) {
        throw new ApiException(FILE_READ_FAILED);
    }
    return imageUrl;
}

private String generateFileName(String originalFilename) {
    return UUID.randomUUID() + "-" + originalFilename.replace(" ", "_");
}
public void deleteFile(String fileUrl) {
    try {
        URL url = new URL(fileUrl);
        String path = url.getPath();
        String key = path.substring(1);
        String decodedKey = URLDecoder.decode(key, StandardCharsets.UTF_8); // ํ•œ๊ธ€ ๋˜๋Š” ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด

        s3Template.deleteObject(bucket, decodedKey);
    } catch (MalformedURLException e) {
        throw new ApiException(INVALID_FILE_URL_FORMAT);
    }
}

 

์ฐธ๊ณ  ์ž๋ฃŒ

https://hinweis.tistory.com/111

https://white-developer.tistory.com/75

https://spring.io/projects/spring-cloud-aws#learn