AWS(SDK java v2) S3 적용해보기

최준호·2022년 8월 16일
0

AWS

목록 보기
6/10
post-thumbnail

😂 AWS S3 다시 ㅜㅜ

지난 글에 S3를 적용하는 글이 있었는데 해당 글은 com.amazonaws (v1)을 적용하여 진행했던 글이였기 때문에 v2로 다시 진행하려고 한다...ㅜ

📗 AWS S3

참고 AWS 공식 문서 git-hub
참고 AWS 공식 문서 (SDK java v2)

📄 gradle 추가하기

implementation platform('software.amazon.awssdk:bom:2.17.230')
implementation 'software.amazon.awssdk:s3'

작성 중인 22.08.16 기준 git에서 사용한 버전과 동일한 버전으로 gradle로 추가해주었다.

📄 S3Client 정의하기

@Configuration
@RequiredArgsConstructor
public class S3ClientConfig {
    private final Environment env;
    @Bean
    public S3Client amazoneS3(){
        AwsBasicCredentials credentials = AwsBasicCredentials.create(env.getProperty("cloud.s3.access-id"), env.getProperty("cloud.s3.secret-key"));

        return S3Client.builder()
        .region(Region.AP_NORTHEAST_2)
        .credentialsProvider(StaticCredentialsProvider.create(credentials))
        .build();
    }
}

참고 AWS 공식문서 java sdk(v2) 자격 증명

✍ putObject()

📄 소스 작성

import java.io.IOException;
import java.util.List;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import lombok.extern.slf4j.Slf4j;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;

@Service
@Slf4j
public class S3V3ServiceImpl implements S3V3Service{
    private S3Client s3Client;
    private String bucketName;
    private S3Dao s3Dao;
    private Environment env;

    public S3V3ServiceImpl(Environment env, S3Client s3Client, S3Dao s3Dao) {
        this.s3Client = s3Client;
        this.s3Dao = s3Dao;
        bucketName = env.getProperty("cloud.s3.bucket");
        this.env = env;
    }

	...

    @Override
    @Transactional
    public int putObject(List<MultipartFile> files) {
        try{
            for(MultipartFile file : files){
                String fileName = file.getOriginalFilename();
                String contentType = file.getContentType();
                String path = "juno/";

                PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(path+fileName)
                    .contentType(contentType)
                    .contentLength(file.getSize())
                    .build();
                PutObjectResponse response = s3Client.putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));
                
                if(response.sdkHttpResponse().statusText().orElse("FAIL").equals("OK")){
                    s3Dao.insertImage(new ImageInsertDto(fileName, path, contentType));
                }else{
                    throw new IllegalStateException("AWS에 파일을 올리는데 실패했습니다.");
                }
            }
        }catch(IOException ie){
            log.error("파일을 읽어들이는데 에러가 발생했습니다.");
            log.error(ie.getMessage());
            throw new RuntimeException(ie.getMessage());
        }catch (S3Exception ae){
            log.error("AWS와 통신에 문제가 발생했습니다.");
            log.error(ae.getMessage());
            throw new RuntimeException(ae.getMessage());
        }catch (IllegalStateException se){
            log.error("AWS와 통신에 문제가 발생했습니다.");
            log.error(se.getMessage());
            throw new RuntimeException(se.getMessage());
        }
        
        return 0;
    }

}

이제 코드를 실행해보자.

📄 테스트

파일을 2개 선택해서 올리면

파일이 잘 올라간 것을 확인할 수 있다.

✍ getObjectData()

📄 소스 작성

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import lombok.extern.slf4j.Slf4j;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;

@Service
@Slf4j
public class S3V3ServiceImpl implements S3V3Service{
    private S3Client s3Client;
    private String bucketName;
    private S3Dao s3Dao;
    private Environment env;

    public S3V3ServiceImpl(Environment env, S3Client s3Client, S3Dao s3Dao) {
        this.s3Client = s3Client;
        this.s3Dao = s3Dao;
        bucketName = env.getProperty("cloud.s3.bucket");
        this.env = env;
    }
    
    ...

    @Override
    public void getObject(String path) {
        try {
            GetObjectRequest objectRequest = 
                GetObjectRequest.builder()
                    .key(path)
                    .bucket(bucketName)
                    .build();
            ResponseBytes<GetObjectResponse> response = s3Client.getObjectAsBytes(objectRequest);

            String text = new String(response.asByteArray(), StandardCharsets.UTF_8);
            log.debug("-------- 파일 내용 --------");
            log.debug(text);
            log.debug("-------- 파일 내용 --------");
        }catch (S3Exception ae){
            log.error("AWS와 통신에 문제가 발생했습니다.");
            log.error(ae.getMessage());
            throw new RuntimeException(ae.getMessage());
        }
    }

}

다음과 같이 파일 내용을 읽어보는 로직을 작성했다.

그전에 s3에 test용도 txt 파일을 올려두자!

나는 다음과 같이 text.txt 테스트용 파일을 올려두었다.

내용은

다음과 같고 로그에도 똑같이 찍혀나오면 된다.

📄 테스트

다음과 같이 요청했고

파일 내용을 잘 읽어왔다!

✍ ListObjects()

📄 소스 작성

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import lombok.extern.slf4j.Slf4j;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.ListObjectsRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Object;

@Service
@Slf4j
public class S3V3ServiceImpl implements S3V3Service{
    private S3Client s3Client;
    private String bucketName;
    private S3Dao s3Dao;
    private Environment env;

    ...

    @Override
    public void getObjectList(String prefix){
        ListObjectsRequest listObjectsRequest = 
            ListObjectsRequest.builder()
                .bucket(bucketName)
                .build();
        ListObjectsResponse response = s3Client.listObjects(listObjectsRequest);
        List<S3Object> contents = response.contents();
        for(S3Object obj : contents){
            log.debug("bucket name = {}",obj.key());
            log.debug("key = {}",obj.owner());
        }
    }
}

s3 storage의 object들을 읽어오는 getObjectList()를 작성했다.

📄 테스트

다음과 같이 요청했고

로그로 잘 찍혀나왔다.

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글