[캡스톤 디자인] 1. SpringBoot와 AWS S3 연동, 이미지 전송하기

박상혁·2023년 4월 12일
0

Project

목록 보기
1/14

개요

SpringBoot 프로젝트에서 AWS S3 storage를 이용하여 이미지를 저장하는 방법에 대해 소개하고자 합니다.

목차

  1. flow chart
  2. class diagram
  3. 과정 소개

사전지식

  • I/O Stream
  • springboot 기본구조
  • AWS S3IAM

본론

flow chart

AWS에서 제공하는 S3 library를 통해 SpringBoot에서 이용

스트림을 사용하여(AmazonS3 클라이언트 또는 TransferManager를 통해) 객체를 Amazon S3에 업로드.

class diagram

다음과 같은 diagram 가짐

mark 및 reset 기능을 가진 Stream 객체를 사용해야 합니다.
이는 File, FileInputStream이 지원합니다.

과정

1. gradle 프로젝트에 다음과 같은 의존성 추가

dependencies {
    implementation 'com.amazonaws:aws-java-sdk-s3:1.12.420'
    implementation 'com.amazonaws:aws-java-sdk-core:1.12.420'
}

2. 설정 파일 생성

@Configuration
public class AmazonS3ClientBeanConfig {
    @Value("${aws.accessKey}")
    private String accessKey;

    @Value("${aws.secretKey}")
    private String secretKey;

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

    @Bean
    public AmazonS3 awsS3Client() {
        AWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
        return AmazonS3ClientBuilder.standard()
                .withRegion(Regions.fromName(region))
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .build();
    }
}
  • AWS 서비스 생성

    각AWS 서비스에는 서비스 API의 각 작업에 대한 메서드가 포함된 서비스 인터페이스가 있습니다.
    AmazonS3를 예로 들면, 버킷생성, 버킷 삭제, 버킷 안의 파일 다운로드, 업로드 등의 메서드가 포함되어 있습니다.
    이러한 AWS 서비스 객체를 만들기 위한 Builder 객체가 각각 존재합니다.
    AmazonDynamoDBClientBuilder, AmazonS3ClientBuilder ...

저희는 Amazon S3 서비스를 사용할 예정이므로 AmazonS3ClientBuilder객체를 생성해야 합니다.
해당 객체는 팩토리 메서드인 standard()를 통해 빌더 객체를 가져오고
지역, 자격 증명과 관련된 정보를 추가하고 빌드 build()를 통해 빌드함으로써
AWS 자격 증명 공급자 객체인 AmazonS3 객체를 리턴합니다.

해당 객체를 Spring의 Bean으로 등록함으로써
앞으로 해당 객체를 Service에서 사용할 수 있게 합니다.

  • S3 버킷 접속 가능한 IAM 자격 설정

AWS SDK for Java 튜토리얼에 따르면, accessKey, secretKey의 자격 증명 정보를 빌더 클래스에 추가하는 2가지 방법이 있습니다.
그 중에서 저는 AWSStaticCredentialsProvider 객체를 사용하는 방법인 임시 자격 증명을 명시적으로 지정을 사용했습니다.

  1. 위 코드와 같이 BasicAWSCredentials 객체에 key 정보를 인수에 넣고 인스턴스화
  2. 이를 AWSCredentials 변수로 만듬
  3. AWSStaticCredentialsProvider에 인수로 해당 변수를 넣고 Builder

awsKeyid와 accessKey의 정보는 변수로 만든 후 @Value를 통해 .yml 설정파일에서 가져올 수 있도록 구현하였습니다.

3. 버킷에 Object 저장, 인출, 삭제 로직 구현

MVC 패턴에 맞게 Service 클래스를 생성하여 해당 메서드를 각각 구현합니다.

@Component
@RequiredArgsConstructor
public class AwsS3StorageService implements StorageService {

    private static final Logger logger = LoggerFactory.getLogger(AwsS3StorageService.class);

    @Value("${aws.bucket.name}")
    private final String bucketName;

    private final AmazonS3 amazonS3Client;

    public URL storedObject(MultipartFile file, String fileName, String contentType) {...}

    public S3Object fetchObject(String awsFileName) {...}

    public void deleteObject(String key) {...}
    }
}
  • @Component
    SpringBoot Application이 실행될 때 @ComponentScan에 의해 @Component가 있는 클래스에 타입에 맞는 Bean을 주입시켜줍니다.
    전에 만들었던 awsS3Client()의 Bean을 주입시켜줍니다.

  • Logger
    해당 클래스안의 메서드를 실행할때 진행상황이나 에러 등을 기록하는 곳입니다.
    <<추후에 Log에 관하여 포스팅 할 예정>>

  • 전처리 과정
    bucket 이름과 AmazonS3 객체 그리고 log 환경이 구성되어야 합니다.
    이후 본격적으로 저장, 인출, 삭제 메서드를 구현합니다.

  • Exception
    AmazonServiceException은 AWS 서비스와 상호작용하는 과정에서 발생하는 예외입니다. 이는 AWS 서비스로부터 예외 코드와 함께 반환됩니다.
    AmazonClientException은 클라이언트의 문제로 발생하는 예외입니다. 따로 반환되는 내용은 없어서 따로 error()메서드로 지정해주었습니다.
    <<추후에 Exception에 관하여 포스팅 할 예정>>

이후 AmazonS3의 메서드를 이용하여
try-catch 구문을 사용해 각 메서드를 구현하였습니다.

자세한 코드구현은 github 참조

Controller 구현

image 파일을 받아야 하는 만큼 해당 파일을 Java 객체로 변환할 수 있어야 합니다.
이를 도와주는 어노테이션인 @ModelAttribute를 사용하여 구현하였습니다.

결과

이미지(.png) 결과를 보여주는 api로 실험한 결과
다음과 같이 성공적으로 S3 bucket으로부터 png 파일을 받아올 수 있었습니다.

결론

AWS S3 라이브러리를 통해 이미지를 S3에 업로드하고 다운로드 하는 과정을 알아보았습니다.

Spring에서는 AWS 서비스를 좀 더 쉽게 이용하기 위해 Spring Cloud AWS를 지원합니다.
다음에는 이를 이용해서 한번 구현해보겠습니다.

참조

AWS SDK for Java1.x 버전 1.x용 개발자 가이드
Log4j - Apache Log4j™ 2
@RequestBody vs @ModelAttribute

profile
개발 노트

0개의 댓글