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
https://jojoldu.tistory.com/300
https://shj7242.github.io/2017/12/28/Spring34/
https://merrily-code.tistory.com/142?category=938924
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=gnsgmlckdgk&logNo=221347051260
'Spring' 카테고리의 다른 글
Spring Controller를 REST 방식으로 변화 - Rest API (0) | 2022.02.23 |
---|---|
스프링 MVC에 대한 간단 정리 (0) | 2022.02.09 |
스프링 프레임워크의 특징 및 의존성 주입 (0) | 2021.12.06 |
스프링 @ExceptionHandler 를 통한 예외 처리 (0) | 2021.10.02 |
SpringBoot Controller Test 작성 및 spring-security에서의 test (0) | 2021.08.31 |