티스토리 뷰

프로그래밍/AWS

[AWS] AWS S3 파일 업로드

Reference M1 2022. 7. 13. 09:31

오늘 포스팅 내용은 AWS S3 파일 업로드에 대해 정리해보자.

 

Bucket 생성 및 권한(정책) 수정

AWS 콘솔에서 S3 메뉴에서 버킷 생성을 하고 권한 탭에서 버킷 정책을 수정해야 한다.

버킷 정책은 정책 생성기를 통해 만들고, 필요한 Action 목록은 아래와 같다.

  • GetObject
  • GetObjectAcl
  • PutObject
  • PutObjectAcl
  • DeleteObject
  • ListBucket

 

사용자 및 권한 추가

AWS 콘솔에서 IAM 메뉴에서 사용자를 추가하고 S3 접근을 위한 권한을 설정해야 된다.

S3 파일 객체에 접근하기 위해서는 AmazonS3FullAccess 정책을 사용자에 연결해야 된다. 또한 사용자 추가 시 발급받은 액세스 키 정보를 잘 보관하고 있어야 한다.

 

pom.xml 및 *.yml 파일

aws sdk를 사용하기 위해 라이브러리를 추가하고, yml 파일을 통해 관리될 수 있도록 IAM 설정 정보를 작성 하자.

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.12.192</version>
</dependency>
cloud:
  aws:
    credentials:
      access-key: IAM User access-key
      secret-key: IAM User secret-key
    region:
      static: ap-northeast-2
    s3:
      bucket: 버킷이름
    stack:
      auto: false

 

AwsS3config.java

yml 파일로 관리되는 IAM 설정 정보를 Bean에 주입하기 위해 작성한다.

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
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 AwsS3Config {

    @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 AmazonS3Client amazonS3Client() {
        BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
        return (AmazonS3Client) AmazonS3ClientBuilder.standard()
                .withRegion(region)
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .build();
    }
}

 

AwsService.java

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class AwsS3Service {

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

    @Autowired
    private AmazonS3Client amazonS3Client;

    /**
     * s3 업로드(이미지)
     *
     * @param bufferedImage
     * @param contentType
     * @param fileName
     * @return
     * @throws IOException
     */
    public String uploadImageFileToAwsS3(BufferedImage bufferedImage, String contentType, String fileName)
            throws IOException {

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        String imgFileExt = contentType.substring(contentType.indexOf("/") + 1);
        ImageIO.write(bufferedImage, imgFileExt, byteArrayOutputStream);

        // set metadata
        ObjectMetadata objectMetadata = new ObjectMetadata();
        byte[] bytes = byteArrayOutputStream.toByteArray();
        objectMetadata.setContentLength(bytes.length);
        objectMetadata.setContentType(contentType);

        try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
            return this.createFile(fileName, inputStream, objectMetadata);
        } catch (IOException e) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "S3 이미지 업로드에 실패했습니다.");
        }
    }

    /**
     * S3 업로드(이미지 외 파일)
     * 
     * @param multipartFile
     * @param fileName
     * @return
     */
    public String uploadFileToAwsS3(MultipartFile multipartFile, String fileName) {

        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(multipartFile.getSize());
        objectMetadata.setContentType(multipartFile.getContentType());

        try (InputStream inputStream = multipartFile.getInputStream()) {
            return this.createFile(fileName, inputStream, objectMetadata);
        } catch (IOException e) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "S3 업로드에 실패했습니다.");
        }
    }

    /**
     * 파일 생성
     * 
     * @param fileName
     * @param inputStream
     * @param objectMetadata
     * @return
     */
    private String createFile(String fileName, InputStream inputStream, ObjectMetadata objectMetadata) {

        amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, inputStream, objectMetadata)
                .withCannedAcl(CannedAccessControlList.PublicRead));

        log.info("AmazonS3 putObject file complete!");

        return amazonS3Client.getUrl(bucket, fileName).toString();
    }

    /**
     * 파일 이동
     * 
     * @param fileName
     * @param targetFileName
     */
    public void moveFileToAwsS3(String fileName, String targetFileName) {

        this.copyFile(fileName, targetFileName);
        this.deleteFile(fileName);
    }
    
    /**
     * 파일 이동
     * 
     * @param fileName
     * @param targetFileName
     */
    public void copyFile(String fileName, String targetFileName) {

        amazonS3Client.copyObject(new CopyObjectRequest(bucket, fileName, bucket, targetFileName));
        log.info("AmazonS3 copyObject file complete!");
    }

    /**
     * 파일 삭제
     * 
     * @param fileName
     */
    private void deleteFile(String fileName) {

        amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, fileName));
        log.info("AmazonS3 deleteObject file complete!");
    }

    /**
     * 파일 객체 정보
     * 
     * @param fileName
     * @return
     */
    public S3Object getObject(String fileName) {

        log.info("AmazonS3 getObject file complete!");
        return amazonS3Client.getObject(bucket, fileName);
    }
}

 

 

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함