Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ec2
  • 코딩테스트
  • kotlin
  • MariaDB
  • 문자열
  • 파이썬
  • 다이나믹 프로그래밍
  • 코틀린 인 액션
  • elasticsearch
  • 코틀린
  • til
  • SQL
  • Android
  • Wil
  • webflux
  • rsocket
  • java
  • spring
  • 에라토스테네스의 체
  • 안드로이드
  • 레포지토리
  • 프리코스
  • Docker
  • 백준
  • kibana
  • 우아한테크코스
  • 프로그래머스
  • grafana
  • 내림차순
  • enum

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

Spring

[Spring] AWS S3 서비스를 사용하여 이미지 업로드

2023. 5. 9. 01:46

1. 버킷 생성

 

 

설정한 후 버킷을 생성해준다.

 

권한 탭 > 버킷 정책 > 편집

 

Principal은 *, Actions는 DeleteObject, GetObject, PutObject 를 선택해주고, ARN은 이전 페이지에 있던 ARN을 복사해서 붙여넣는다.

Add Statement를 클릭하면 Generate Policy를 통해 정책을 생성하자. 생성된 JSON 타입 정책을 이전 페이지에 붙여넣으면 된다.

 

CORS 설정하는 경우는 많지 않았지만, 그래도 혹시 모르니 미리 설정하기로 했다.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]

 

2. IAM 사용자 생성 및 권한 부여

사용자 이름을 정해준다.

 

다음을 클릭하고, 직접 정책 연결을 선택하여 AmazonS3FullAccess 를 추가한다.

다음을 클릭하고, 사용자 생성을 해준다.

 

3. 액세스 키 생성

생성한 사용자 이름을 클릭 > 보안 자격 증명 탭 > 액세스 키 만들기 클릭

 

대안은 아무거나 선택해도 된다.

발급받은 Access Key와 Secret Access Key를 따로 저장해두거나, cvs 파일을 받아두길 바란다.

 

4. build.gradle 설정

aws s3를 사용하기 위해 build.gradle에 의존성을 추가하자.

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

 

5. application.yml 설정

필자는 외부에 공개되면 안되는 설정 정보는 application-secret.yml 과 같이 따로 관리하여 .gitignore에 추가했다.

사용하는 설정 파일에 다음과 같이 작성하자.

cloud:
  aws:
    credentials:
      access-key: 액세스키 #IAM ACCESS_KEY
      secret-key: 시크릿액세스키 #IAM SECRET_KEY
    s3:
      bucket: 버킷이름 #버킷 이름
    region:
      static: ap-northeast-2
    stack:
      auto: false

 

6. Config 클래스 추가

다음과 같이 설정파일을 추가해준다.

package com.team10.whatis.global.config;

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

@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
    public AmazonS3 amazonS3Client() {
        AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

        return AmazonS3ClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withRegion(region)
                .build();
    }
}

 

7. Controller와 Service

컨트롤러에 다음과 같은 메서드를 작성해주었다. 본인 프로젝트에 맞게 작성해주면 된다.

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseDto<String> uploadImage(@RequestPart(value = "image") MultipartFile image) {
    return postService.uploadImage(image);
}

서비스에는 다음과 같은 메서드를 작성해주었다. return값으로 업로드된 이미지의 url을 반환했다.

@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class PostService {

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

    /**
     * s3 이미지 업로드
     */
    public String uploadImage(MultipartFile image) {
        //중복된 이름 방지를 위한 UUID 붙이기
        String fileName = UUID.randomUUID() + "-" + image.getOriginalFilename();

        //메타 데이터 설정
        ObjectMetadata objMeta = new ObjectMetadata();
        objMeta.setContentType(image.getContentType());
        objMeta.setContentLength(image.getSize());

        try {
            objMeta.setContentLength(image.getInputStream().available());
            //s3에 파일 업로드
            amazonS3.putObject(bucket, fileName, image.getInputStream(), objMeta);
        } catch (IOException e) {
            throw new IllegalArgumentException("이미지 업로드에 실패했습니다.");
        }
        return amazonS3.getUrl(bucket, fileName).toString();
    }
}

 

PostMan에서 form-data로 요청을 보내고 확인해보면 s3 버킷에 정상적으로 업로드 된다.

728x90

'Spring' 카테고리의 다른 글

[Spring] @RequestParam으로 Enum 타입 매개변수 받기  (0) 2023.05.15
[Spring] @RequestPart 사용하여 MultipartFile과 Dto 함께 받기, Postman 테스트  (0) 2023.05.14
[Spring] EC2 서버 실행 시, Web server failed to start. Port 8080 was aleady in use 해결  (0) 2023.05.08
[Spring] EC2 Connection Time 지정  (0) 2023.05.08
[Spring] SpringBoot EC2에서 AWS RDS MariaDB 연동 및 배포  (2) 2023.05.08
    'Spring' 카테고리의 다른 글
    • [Spring] @RequestParam으로 Enum 타입 매개변수 받기
    • [Spring] @RequestPart 사용하여 MultipartFile과 Dto 함께 받기, Postman 테스트
    • [Spring] EC2 서버 실행 시, Web server failed to start. Port 8080 was aleady in use 해결
    • [Spring] EC2 Connection Time 지정
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바