상세 컨텐츠

본문 제목

[TIL#32-1] TestyPie] S3 세팅하기

내배캠/Testy Pie(최종 프로젝트)

by DK9 2024. 1. 12. 09:57

본문

들어가기에 앞서 AWS에서 S3 생성과 관련 작업들은 생략하고 코드 부분만 집중적으로 보겠다.

 

1. Build.gradle

 

dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
}

 

의존성을 추가한다.

 

2. .properties 혹은 .yml

 

# S3
cloud.aws.region.static= ap-northeast-2
cloud.aws.s3.bucket= testy-pie
cloud.aws.stack.auto=false
cloud.aws.credentials.accessKey= 여기 엑세스키
cloud.aws.credentials.secretKey= 여기 시크릿키

 

S3관련된 설정을 추가해준다. 같은 곳에 기재해도 되고 .properties 나 .yml을 2개 만들어서 accessKey와 secretKey를 분리해도 된다.

2-1. 분리하게 될 경우

 

 

이처럼 2개로 분리하여 키값들을 따로 관리할 경우, 키 값들이 들어있는 .properties를 사용할 수 있도록  application.properties 에 아래의 코드를 추가해줘야한다.

spring.profiles.active=s3

 

3. S3Config

 

@Configuration
public class S3Config {

    @Value("${cloud.aws.credentials.access-key}")
    private String iamAccessKey;

    @Value("${cloud.aws.credentials.secret-key}")
    private String iamSecretKey;

    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    public AmazonS3Client amazonS3Client() {
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(iamAccessKey, iamSecretKey);
        return (AmazonS3Client) AmazonS3ClientBuilder.standard()
                .withRegion(region).enablePathStyleAccess()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .build();
    }
}

 

S3를 사용하기 위한 Config 클래스를 작성해준다.

 

 

4. S3Uploader

 

@Slf4j
@RequiredArgsConstructor
@Component
public class S3Uploader {

    private final AmazonS3Client amazonS3Client;

    @Value("${cloud.aws.s3.bucket}")
    private String bucket;

    public String upload(MultipartFile multipartFile, String dirName) throws IOException {
        File uploadFile = convert(multipartFile).orElseThrow(
                () -> new IllegalArgumentException("MultipartFile -> File로 전환이 실패했습니다."));

        return upload(uploadFile, dirName);
    }

    private String upload(File uploadFile, String dirName) {
        String fileName = dirName + "/" + uploadFile.getName();
        String uploadImageUrl = putS3(uploadFile, fileName);
        removeNewFile(uploadFile);
        return uploadImageUrl;
    }

    private String putS3(File uploadFile, String fileName) {
        amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(
                CannedAccessControlList.PublicRead));
        return amazonS3Client.getUrl(bucket, fileName).toString();
    }

    private void removeNewFile(File targetFile) {
        if (targetFile.delete()) {
            log.info("파일이 삭제되었습니다.");
        } else {
            log.warn("파일이 삭제되지 못했습니다.");
        }
    }

    private Optional<File> convert(MultipartFile file) throws IOException {
        File convertFile = new File(file.getOriginalFilename());
        System.out.println("convertFile = " + convertFile);
        if (convertFile.createNewFile()) {
            try (FileOutputStream fos = new FileOutputStream(convertFile)) {
                fos.write(file.getBytes());
            }
            return Optional.of(convertFile);
        }
        return Optional.empty();
    }
}

 

S3에 정적 파일을 올리는 역할을 하는 S3Uploader 클래스이다. 이를 Service 영역에 둘 지, 아니면 다른 영역(utils, handlers 등)에 두고 사용할 지는 개인의 판단하에 로직을 정하고 사용하면 될 것 같다. 본인의 경우, domain에 util 이라는 디렉토리를 따로 생성해서 보관하고 있다. 정답은 없다.

 

코드를 보면 맨 처음에 AmazonS3Client를 @RequiredArgsConstructor 어노테이션으로 의존성 주입을 받는다. bucket의 이름으로 @Value("${cloud.aws.s3.bucket}")을 사용하고 이는 위에서 작성했던 S3Config.java파일에서 가져온다.

 

MultipartFile을 전달받아서 S3에 전달가능한 형태인 File을 생성하고, 전환된 File을 S3에 public 읽기 권한으로 전송한다. 그리고 로컬에 생성된 File을 삭제한 뒤, 업로드된 파일의 S3 URL 주소를 반환합니다.

 

위 코드에서 dirName은 AWS S3 버킷 내 디렉토리를 의미한다. 이 디렉토리 같은 경우 .yml 혹은 .properties 에서 default로 설정해 줄 수도 있지만, 로직 구현의 유연성을 위해서 따로 기재하지 않고 사용하는 서비스마다 다른 디렉토리로 지정하는 것이 옳다고 생각하여 위와 같이 매개변수로 받도록 하였다. 정답은 없다.

 

 

추가로

어렵다. 정보검색이 제일 힘들다. 그치만 재밋다.

 

 

참고 블로그

https://studyandwrite.tistory.com/498

 

Springboot, AWS S3를 이용해서 이미지 처리하기 - (2)

0. 들어가면서 이번 시간에는 지난 포스팅에 이어 Springboot와 AWS S3를 이용해서 이미지를 업로드하는 과정을 코드로 살펴보도록 하겠습니다. 지난 포스팅에서 S3 버킷 생성과 IAM 사용자 생성을 다

studyandwrite.tistory.com

 

https://develop-writing.tistory.com/128

 

[AWS] Springboot에 AWS S3 연동 (이미지, 동영상 업로드)

안녕하세요? 이번 시간엔 SpringBoot & AWS S3 연동하기를 진행해보려고 합니다. 따라 하시기만 해도 로컬에서 이미지, 동영상 파일 업로드가 가능하고, EC2에 배포한 환경에서도 파일 업로드가 가능

develop-writing.tistory.com

 

관련글 더보기