본문 바로가기

카테고리 없음

spring s3 파일 upload

build.gradle

 

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

 

aws.yml

 

cloud:
  aws:
    credentials:
      accessKey: IAM-accessKey
      secretKey: IAM-secretKey
    s3:
      bucket: bucketName
    region:
      static: ap-northeast-2
    stack:
      auto: false

 

main class

 

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class Hanghae99cloneApplication {

   public static final String APPLICATION_LOCATIONS = "spring.config.location="
      + "classpath:application.properties,"
      + "classpath:aws.yml";

   public static void main(String[] args) {
      new SpringApplicationBuilder(Hanghae99cloneApplication.class)
         .properties(APPLICATION_LOCATIONS)
         .run(args);
   }
}

 

ImageController

 

import com.sparta.hanghae99clone.config.S3Uploader;
import java.io.IOException;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RequiredArgsConstructor
@RestController
public class ImageController {

    private final S3Uploader s3Uploader;

    @PostMapping("/images")
    public String upload(@RequestParam("images") MultipartFile multipartFile) throws IOException {
        return s3Uploader.upload(multipartFile);
    }
}

 

S3 uploader

 

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.PutObjectRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@RequiredArgsConstructor
@Component
public class S3Uploader {

    private static final String IMAGE_UPLOAD_DIR = "static/image";

    private final AmazonS3Client amazonS3Client;

    @Value("${cloud.aws.s3.bucket}")
    public String bucket;  // S3 버킷 이름

    public String upload(MultipartFile multipartFile) throws IOException {
        File uploadFile = convert(multipartFile)  // 파일 변환할 수 없으면 에러
                .orElseThrow(() -> new IllegalArgumentException("error: MultipartFile -> File convert fail"));

        return upload(uploadFile);
    }

    // S3로 파일 업로드하기
    private String upload(File uploadFile) {
        // S3에 저장된 파일 이름 (한글 파일 이름이 올라올 경우 s3에서 문제가 발생함 -> 한글파일 이름을 빼고 UUid 이름만 저장하려고 함)
        // String fileName = dirName + "/" + UUID.randomUUID() + uploadFile.getName();
        String fileName = IMAGE_UPLOAD_DIR + "/" + UUID.randomUUID();
        // s3로 업로드
        String uploadImageUrl = putS3(uploadFile, fileName);
        removeNewFile(uploadFile);
        return uploadImageUrl;
    }

    // S3로 업로드
    private String putS3(File uploadFile, String fileName) {
        amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(
            CannedAccessControlList.PublicRead));
        return amazonS3Client.getUrl(bucket, fileName).toString();
    }

    // 로컬에 저장된 이미지 지우기
    private void removeNewFile(File targetFile) {
        if (targetFile.delete()) {
            log.info("File delete success");
            return;
        }
        log.info("File delete fail");
    }

    // 로컬에 파일 업로드 하기
    private Optional<File> convert(MultipartFile file) throws IOException {
        // "현재 폴더/파일 이름" 정보를 가지고 있는 file 객체 생성
        File convertFile = new File(System.getProperty("user.dir") + "/" + file.getOriginalFilename());
        // 바로 위에서 지정한 경로에 File이 생성됨 (경로가 잘못되었다면 생성 불가능)
        if (convertFile.createNewFile()) {
            try (FileOutputStream fos = new FileOutputStream(convertFile)) {
                // FileOutputStream 데이터를 파일에 바이트 스트림으로 저장하기 위함
                fos.write(file.getBytes());
            }
            return Optional.of(convertFile);
        }
        return Optional.empty();
    }
}

 

Reference

 

https://devlog-wjdrbs96.tistory.com/323

 

[Spring] Spring Boot AWS S3 사진 업로드 하는 법

Spring Boot S3 File Upload 하는 법 이번 글에서는 Spring Boot 로 AWS S3 로 File Upload 하는 법에 대해서 정리해보겠습니다. 먼저 AWS S3 Bucket 생성을 하겠습니다. AWS S3 Bucket 생성 그리고 권한 탭을 들..

devlog-wjdrbs96.tistory.com