1 분 소요

스프링에서 S3에 접근해 파일을 다운로드하고 업로드하는 방법을 알아보자!

S3

의존성 추가

AWS S3 클래스를 사용할 수 있도록 의존성을 추가해주자.

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

application.yml

AWS S3 access key, secret key, region 등의 정보를 설정해주자.
특히 access key, secret key는 Github에 노출돼선 안되므로 Git에 추가하지 않도록 주의하자!
나같은 경우 Github repository의 secrets로 등록해서 활용하고 있다.

cloud:
  aws:
    s3:
      bucket: [bucket 입력]
    stack.auto: false
    region.static: ap-northeast-2
    credentials:
      instance-profile: false
      accessKey: [access key 입력]
      secretKey: [secret key 입력]

S3Config

위에서 설정한 정보들을 가져와서 변수에 초기화하고 활용하면 된다!
S3Config는 S3에 접근하기 위해 먼저 만들어줘야 하는 설정 클래스이다. 다음처럼 만들어주자.

@Configuration
public class S3Config {
    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;
    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;
    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    @Primary
    public BasicAWSCredentials awsCredentialsProvider(){
        return new BasicAWSCredentials(accessKey, secretKey);
    }

    @Bean
    public AmazonS3 amazonS3() {
        return AmazonS3ClientBuilder.standard()
                .withRegion(region)
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentialsProvider()))
                .build();
    }
}
  • AmazonS3은 빈으로 등록해주기 때문에 다른 클래스에서 주입받아 사용할 수 있음

다운로드/업로드

프로젝트에서 사용중인 코드를 그대로 가져왔는데, 파일 이름을 파라미터 storedFileName로 받으면 S3에 접근해서 다운로드하고
다른 업로드까지 한번에 처리하는 코드다.

다운로드는 AmazonS3.getObject()를 사용하고, 파라미터는 GetObjectRequest(버킷명, 파일명)을 넣어주면 된다.
업로드는 AmazonS3.putObject()를 사용하고, 파라미터는 버킷, 파일명, 파일 InputStream, 메타데이터를 넣어주면 된다.
InputStreamgetObject()로 받은 객체 정보를 byte[]를 받고 변환해주었다!

위에서는 버킷을 1개만 등록했지만 프로젝트에서는 crawlingBucket에서 serverBucket로 객체를 옮겨줘야 하는 상황이어서
다음처럼 처리했다.

@Service
@RequiredArgsConstructor
public class S3Service {

    private final AmazonS3 amazonS3;

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

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

    //다운로드 + 업로드
    public void moveS3ObjectToServerBucket(String storedFileName) throws IOException {
        S3Object obj = amazonS3.getObject(new GetObjectRequest(crawlingBucket, storedFileName)); //다운로드
        S3ObjectInputStream objectInputStream = obj.getObjectContent();
        byte[] fileBytes = IOUtils.toByteArray(objectInputStream);
        String fileName = URLEncoder.encode(storedFileName, UTF_8)
                .replaceAll("\\+", "%20")
                .replaceAll("%3A", ":")  //콜론 깨짐 방지
                .replaceAll("%5F", "_"); //언더바 깨짐 방지

        InputStream fileInputStream = new ByteArrayInputStream(fileBytes);
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType("image/*");
        metadata.setContentLength(fileBytes.length);
        amazonS3.putObject(serverBucket, fileName, fileInputStream, metadata); //업로드
    }
}
  • S3Config에서 등록한 AmazonS3를 주입받아 사용
  • crawlingBucket, serverBucketapplication.yml에서 설정한 값 활용

References

카테고리:

업데이트:

댓글남기기