🔻Back-End/Features

[Features] S3 버킷 생성 및 SpringBoot 프로젝트에 연결

_니지 2024. 8. 10. 23:23

클라우드 스토리지인 S3를 사용하여 대용량 데이터를 저장하기 위해 S3 구축 및 SpringBoot 프로젝트에 연결하여 API를 사용해서 파일을 업로드 하는 과정이다!

 

❗S3 버킷 생성

https://radiant515.tistory.com/473

 

[AWS] S3 생성

❗S3란? AWS에서 제공하는 storage 서비스이다. 원하는 어떤 종류의 데이터를 저장하고 보호할 수 있는 기능을 제공한다! ❗Bucket 생성 ❗IAM 생성 버킷을 관리할 수 있는 권한(role)을 생성한다 액세스

radiant515.tistory.com

 

 

❗build.gradle

dependencies {
	..생략..
	implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.3.5'
}

스프링부트 프로젝트에 연결하기 위해서 먼저 AWS 의존성을 추가한다.

 

 

❗application.yml

cloud:
  aws:
    credentials:
      access-key: [AWS 액세스 키]
      secret-key: [AWS 시크릿 키]
    s3:
      bucket: [버킷이름]
    region:
      static: ap-northeast-2

S3 연결을 위한 IAM 생성 시에 저장해준 csv 파일에서 액세스 키와 시크릿 키를 해당하는 자리에 넣어주고, 위에서 생성한 버킷 이름으로 변경해 준다. 

그리고 application.yml 파일에 복붙을 할 때 spring의 하위가 아닌 cloud가 루트가 되게 넣어준다!

 

 

❗예시 코드

package com.flyai.safet.service;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.flyai.safet.exception.BadRequestException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class S3Service {

    private final AmazonS3Client amazonS3Client;

    public String uploadImage(String folderName, String fileName, MultipartFile multipartFile) {
        if(multipartFile == null) {
            return null;
        }
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(multipartFile.getContentType());
        objectMetadata.setContentLength(multipartFile.getSize());
        String uploadFileName = concatFolderName(folderName, fileName);
        try {
            InputStream inputStream = multipartFile.getInputStream();
            amazonS3Client.putObject(
                    new PutObjectRequest([버킷이름], uploadFileName, inputStream, objectMetadata)
                            .withCannedAcl(CannedAccessControlList.PublicRead)
            );
        }
        catch(IOException e) {
            throw new BadRequestException("잘못된 형식의 파일입니다.");
        }
        return getImageUrl(uploadFileName);
    }

    public String concatFolderName(String folderName, String fileName) {
        return folderName + "/" + UUID.randomUUID() + "-" + fileName;
    }

    public String getImageUrl(String uploadFileName) {
        return "https://[버킷이름].s3.ap-northeast-2.amazonaws.com/" + uploadFileName;
    }
}

먼저 파일 업로드 및 조회 기능을 수행해줄 S3Service 파일을 생성한다.

[버킷이름] 부분을 자신이 생성한 버킷으로 변경한다.

 

@ApiOperation(value = "이미지 업로드", notes = "이미지 업로드")
@PostMapping("/image")
public ApiResponse<Image> uploadImage(@RequestPart(name = "images") MultipartFile multipartFile){

    String url = s3Service.uploadImage("test", multipartFile.getOriginalFilename(), multipartFile);

    Image image = Image.builder()
            .url(url)
            .build();

    imageRepository.save(image);

    return new ApiResponse<>(image);
}

 test용 API이다. 1개 또는 여러개의 파일을 MultipartFile 객체로 받아서 이를 업로드할 수 있다. 또한 uploadImage함수의 첫번째 파라미터 부분은 버킷 내에서 저장할 폴더명을 지정할 수 있기 때문에 각 용도에 맞게 수정할 수 있다. 

uploadImage의 리턴값으로 저장된 url이 나오기 때문에 이를 DB에 저장하여 해당 파일이 필요할 때, 저장된 링크를 통해 접근할 수 있다.  

 

API를 실행 시 업로드할 사진을 선택하고 실행을 하면 반환으로 url을 준다. 이 url로 바로 컨텐츠에 직접 접속이 되는지도 확인할 수 있다!

728x90
반응형