Back-end/SpringBoot

AWS S3 사용하는법!

xeunnie 2024. 7. 15. 05:38
728x90
반응형

AWS S3란?

Amazon Simple Storage Service(S3)는 확장 가능하고 고가용성 및 보안성을 갖춘 객체 스토리지 서비스다.

  • @Configuration을 통해 S3 클라이언트 설정
  • 서비스 계층에서 파일 업로드 및 다운로드 기능을 구현
  • 컨트롤러를 통해 RESTful API를 제공

위 과정을 거치면 간편하게 파일 관리 기능을 제공할 수 있고 클라이언트는 웹의 어디에서나 데이터를 저장하고 검색할 수 있다.

주요 특징

  1. 무한대에 가까운 확장성을 가진다. S3는 엄청난 양의 데이터를 저장할 수 있다.
  2. 여러 시설에 데이터를 자동으로 복제해, 99.999999999% (11 9's)의 고가용성 및 내구성을 제공하고 데이터 손실을 방지한다.
  3. 데이터를 암호화할 수 있어, 다양한 규정 준수 요구사항을 충족하는 보안 및 규정 준수 기능을 제공한다.
  4. S3 콘솔 및 다양한 API를 통해 데이터를 쉽게 관리하고 접근할 수 있습니다.

스프링 부트에서 AWS S3 사용하기

1. AWS SDK 의존성 추가

dependencies {
    implementation platform('software.amazon.awssdk:bom:2.20.40') // 이건 버전 유지용
    implementation 'software.amazon.awssdk:s3'
}

2. AWS 자격 증명 설정

방법 1: 환경 변수 사용
export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key
방법 2: AWS 자격 증명 파일 사용 (~/.aws/credentials)
[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

3. S3 클라이언트 설정

스프링 부트 애플리케이션에서 S3 클라이언트 설정

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class S3Config {

    @Bean
    public S3Client s3Client() {
        return S3Client.builder()
                .region(Region.US_WEST_2)  // 원하는 AWS 리전으로 변경
                .credentialsProvider(ProfileCredentialsProvider.create())
                .build();
    }
}

4. S3 서비스 구현

S3를 사용하여 파일을 업로드하고 다운로드하는 서비스 구현

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Object;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

@Service
public class S3Service {

    private final S3Client s3Client;

    @Autowired
    public S3Service(S3Client s3Client) {
        this.s3Client = s3Client;
    }

    public void uploadFile(MultipartFile file, String bucketName, String key) throws IOException {
        File fileObj = convertMultiPartFileToFile(file);
        s3Client.putObject(PutObjectRequest.builder()
                        .bucket(bucketName)
                        .key(key)
                        .build(),
                Paths.get(fileObj.getAbsolutePath()));
        fileObj.delete();
    }

    public byte[] downloadFile(String bucketName, String key) throws IOException {
        S3Object s3Object = s3Client.getObject(GetObjectRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build());

        return Files.readAllBytes(Paths.get(s3Object.key()));
    }

    private File convertMultiPartFileToFile(MultipartFile file) throws IOException {
        File convFile = new File(file.getOriginalFilename());
        FileOutputStream fos = new FileOutputStream(convFile);
        fos.write(file.getBytes());
        fos.close();
        return convFile;
    }
}

5. 컨트롤러 구현

S3 서비스를 사용하여 파일을 업로드하고 다운로드하는 REST 컨트롤러를 구현

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/api/s3")
public class S3Controller {

    private final S3Service s3Service;

    @Autowired
    public S3Controller(S3Service s3Service) {
        this.s3Service = s3Service;
    }

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        String bucketName = "your-bucket-name";
        String key = file.getOriginalFilename();

        try {
            s3Service.uploadFile(file, bucketName, key);
            return new ResponseEntity<>("File uploaded successfully", HttpStatus.OK);
        } catch (IOException e) {
            return new ResponseEntity<>("File upload failed", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @GetMapping("/download/{key}")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String key) {
        String bucketName = "your-bucket-name";

        try {
            byte[] fileData = s3Service.downloadFile(bucketName, key);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", key);
            return new ResponseEntity<>(fileData, headers, HttpStatus.OK);
        } catch (IOException e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

이 외의 추가 설정 및 보안

  1. AWS IAM 콘솔에서 적절한 권한을 가진 역할을 생성하고, EC2 인스턴스 또는 Lambda 함수에 할당할 수 있다.
  2. S3 작업과 관련된 로그를 남기고, CloudWatch와 통합하여 모니터링을 수행할 수 있다.
  3. 버킷 정책을 통해 접근 제어를 설정할 수 있다.
728x90
반응형