본문 바로가기
Spring

springboot 이미지파일을 aws 서버에 보관하고 가져오기(s3)

by khds 2021. 9. 16.

springboot를 다루면서 이미지를 저장해놓고 저장한 이미지 URL을 가져오는 기능이 필요하여 aws를 이용하여 구현해봤다. 

이 글에서는 aws 사이트에서 이미지를 업로드하고 spring에서는 업로드한 이미지에 접근할 수 있는 이미지 URL을 가져오는 기능만 구현했으며 이미지 업로드 기능, 삭제 기능 같은 다른 기능들은 참고에 적어놓은 다른 블로그들을 확인해 보길 바란다. 또한 이 글에서는 로컬 환경에서의 설정만을 하였고 배포 환경에서의 설정에 대해서도 확인학 싶다면 참고에 다른 블로그들을 확인해 보길 바란다.

물론 이미지뿐만 아니라 다른 파일도 aws에 저장할 수 있지만 여기서는 이미지 파일만을 다루겠다.

 

먼저 aws에 로그인을 한다. 무료 계정으로 해도 특별히 과도한 기능을 사용하지 않는 한 지장은 없다.

우리가 사용할 기능은 aws에 S3기능이다. S3 저장소는 최대 1년간 5GB까지 무류로 사용할 수 있다.

 

S3에 들어가면 아래와 같이 버킷 만들기를 클릭하면 내가 이미지를 저장해놓을 폴더 같은 기능을 하는 버킷을 만들 수 있다.

 

 

버킷 만들기를 누르면 아래와 같이 세부 설정창이 나온다. 버킷 이름은 자기가 원하는 데로 작성하고  AWS 리전이라는 곳은 아래 사진과 같이 자신의 지역과 가까운 곳으로 설정한다. 그렇게 하면 그 지역에 서버가 만들어져서 더 빠르게 접근 가능하다.

 

 

다음은 모든 퍼블릭 액세스 차단의 체크를 해제한다.

 

 

만들었으면 만든 버킷을 클릭하고 아래와 같이 권한 탭에 들어간다. 

 

 

아래로 내리다 보면 아래와 같이 버킷 정책이 나올 텐데 이를 편집해 줘야 한다.

 

 

편집을 누르고 아래의 내용을 적는다.

 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AddPerm",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::버킷 이름/*"
    }
  ]
}

 

이렇게 하면 퍼블릭에서 접근이 가능해진다.

 

그리고 이미지 업로드를 하면 아래와 같이 URL이 있을 것이다.

 

 

저 URL을 클릭하면 사진을 확인할 수 있고 잘 연결이 된다면 성공한 것이다.

 

 

자, 그럼 이제 스프링에서 이 이미지 url을 가져와보자. 그전에 하나 설정해야 하는 것이 있다.

aws에 IAM이다. 여기서 사용자를 만들면 특정 시크릿키가 나오는데 이를 통해 스프링에서 aws에 접근이 가능하다.

 

우선 아래와 같이 사용자 추가를 누른다.

 

사용자 이름을 적고 액세스 키 - 프로그래밍 방식 액세스를 선택한다.

 

그리고 아래 화면과 같이 설정한다. 

 

 

계속 넘기고 나서 사용자를 만들었으면 아래와 같이 액세스 키와 비밀 액세스 키가 나올 것이다. 이를 통해 스프링에서 aws에 S3에 접근할 수 있다.

 

 

이제 스프링 코드를 살펴보겠다.

나는 aws 폴더를 만들어서 awsS3에 대한 기능을 담아놨다. 

 

우선 의존성에 'com.amazonaws:aws-java-sdk'를 추가한다.  

나는 gradle로 하였고 아래와 같이 추가하였다.

 

 

그리고 작성한 코드를 살펴보겠다.

package sin.sin.aws;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AwsS3Config {

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

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

    @Value("${cloud.aws.credentials.accessKey}")
    private String accessKey;

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

    private AmazonS3 amazonS3;

    @Bean
    public AmazonS3 amazonS3Client() {
        AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setProtocol(Protocol.HTTP);
        this.amazonS3 = new AmazonS3Client(credentials, clientConfig);
        amazonS3.setEndpoint(region);

        return amazonS3;
    }

    @Bean
    public String getBucket() {
        return bucket;
    }
}

 

package sin.sin.aws;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import java.io.File;

public class S3Util {

    private AmazonS3 amazonS3;
    private String bucketName;

    public S3Util(AmazonS3 amazonS3, String bucketName) {
        this.amazonS3 = amazonS3;
        this.bucketName = bucketName;
    }

    public String getFileURL(String fileName) {
        String imgName = (fileName).replace(File.separatorChar, '/');
        return amazonS3.generatePresignedUrl(new GeneratePresignedUrlRequest(bucketName, imgName))
            .toString();
    }
}

 

그리고 기본적인 awsS3에 설정을 위해서 application-aws.properties를 만들고. gitignore에 등록을 해놔서 git에 올라가 개인정보가 외부에 노출되는 것을 막는다. application.properties에 application-aws 내용을 포함시키도록 아래와 같은 코드를 추가한다.

 

 

application-aws.properties  에 적힌 내용은 아래와 같다.

 

cloud.aws.credentials.accessKey= 발급받은 accessKey
cloud.aws.credentials.secretKey= 발급받은 secretKey
cloud.aws.s3.bucket= 버킷이름
cloud.aws.region.static=s3.ap-northeast-2.amazonaws.com
cloud.aws.stack.auto=false
cloud.aws.credentials.instanceProfile=true

 

위의 정보들을 @Value로 가져와서 사용하게 되는 것이다.

 

 

Service에서 위 기능을 사용할 때는 아래와 같은 로직으로 이미지 URL을 가지고 왔다.

private final AwsS3Config awsS3Config;

...

private String getImageUrl(String fileName){
    S3Util s3Util = new S3Util(awsS3Config.amazonS3Client(), awsS3Config.getBucket());
    String imageUrl = s3Util.getFileURL(fileName);

    return imageUrl;
}

 

위에 S3를 만드는 과정에서 넣은 이미지인 heart.png를 fileName에 넣으면 그에 해당하는 imageUrl을 얻을 수 있는 것이다. 

 

 

 

참고

https://klyhyeon.tistory.com/170

 

10. AWS EC2 + Spring boot (8) - AWS S3 이미지 파일 업로드

업데이트: 210311 웹사이트에 필요한 외부 파일(img, txt)은 로컬 폴더에서 관리하고 있었습니다. 하지만 서버 배포를 AWS EC2를 통해 ubuntu에서 하므로 Amazon S3를 이용하기로 결정했습니다. 주요 결정

klyhyeon.tistory.com

 

https://jojoldu.tistory.com/300

 

SpringBoot & AWS S3 연동하기

안녕하세요? 이번 시간엔 SpringBoot & AWS S3 연동하기 예제를 진행해보려고 합니다. 모든 코드는 Github에 있기 때문에 함께 보시면 더 이해하기 쉬우실 것 같습니다. (공부한 내용을 정리하는 Github와

jojoldu.tistory.com

 

https://shj7242.github.io/2017/12/28/Spring34/

 

[AWS] S3 이미지 서버 Spring 과 연동 - 메모 블로그

2017 - 12 - 28 (목) AWS S3 이미지 서버 구성 [ 버킷 ] https://aws.amazon.com/ko/free/?sc_channel=PS&sc_campaign=acquisition_KR&sc_publisher=google&sc_medium=english_cloud_computing_hv_b&sc_content=aws_core_e&sc_detail=aws&sc_category=cloud_computi

shj7242.github.io

 

https://merrily-code.tistory.com/142?category=938924

 

AWS S3를 활용해 이미지 서버 구축하기 - AWS 설정 편

산학프로젝트 진행 중, AWS 사용 비율이 낮다는 지적을 받아 S3를 사용할 곳을 찾고 있었습니다. 그러다 떠올린 것이 S3를 활용해 "유저 프로필 사진을 업로드하는 기능을 추가할 수 있게 하면 어

merrily-code.tistory.com

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=gnsgmlckdgk&logNo=221347051260

 

[스프링 : 오류] 스프링 @Value 어노테이션 항상 null 일때

위와 같이 context.xml에 PropertyPlaceHolderConfigurer 를 등록하고 properties 파일에 있는 값을 들...

blog.naver.com