티스토리 뷰

AWS

AWS S3 + Spring Boot 이미지 업로드

현오쓰 2020. 3. 8. 14:34

 

안녕하세요 :)

오늘은 Spring Boot와 S3를 이용한 이미지 업로드 방법을 알려드리겠습니다.

AWS에서 S3 생성 방법은 생략하고 S3 엑세스키 발급은 간략하게 적겠습니다.

Spring에 중점을 두겠습니다 :) 

 

1. Gradle에 AWS SDK 추가하기

implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.228')
implementation 'com.amazonaws:aws-java-sdk-s3'

 

 

2. AWS로 로그인 하여 S3 엑세스 키 발급받기

 

내  보안 자격증명 -> 사용자 -> 사용자 추가 -> 프로그래밍 방식 엑세스 체크 -> 기존 정책 직접연결 -> S3 Full Access 클릭 

 

3. @Configuration 클래스 생성

package com.cntech.qrcodewebbank.conf;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

@Configuration
public class AWSConfig {

    //프로퍼티스 파일 혹은 yaml 파일에서 s3 access id와 pw를 호출한다.
	@Value("${aws.s3.access-id}")
	private String accessKey;
	
	@Value("${aws.s3.access-pw}")
	private String secretKey;
	
	@Bean
	public BasicAWSCredentials AwsCredentials() {
		BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
		return awsCreds;
	}
	
	@Bean
	public AmazonS3 AwsS3Client() {
		
		AmazonS3 s3Builder = AmazonS3ClientBuilder.standard()
				.withRegion(Regions.AP_NORTHEAST_2)
				.withCredentials(new AWSStaticCredentialsProvider(this.AwsCredentials()))
				.build();
		
		return s3Builder;
	}
}

 

4. AWS 비즈니스 클래스 생성

 

두가지 방법을 업로드 하겠습니다. 하나는 MultipartFile를 업로드 할것이고 하나는 Buffer 이미지를 업로드하겠습니다.

 

package com.cntech.qrcodewebbank.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;

/**
 * @author Sangwon Hyun
 * @since 2020. 2. 20.
 * AWS 관련 비즈니스
 * <PRE>
 * ---------------------
 * 개정이력
 * 2020. 2. 20. Sangwon Hyun : 최초작성
 * </PRE>
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AwsService {

	@Autowired
	private AmazonS3 s3Client;
	@Value("${aws.s3.bucket}")
	private String bucketName; //S3 버킷경로
	/**
	
	  * @Method Name : uploadObject
	  * @작성일 : 2020. 2. 17.
	  * @작성자 : Sangwon Hyun
	  * @Method 설명 : S3 이미지 업로드
	  * @param files
	  * @param bucketKey (실제 저장할 경로)
	  * @throws IOException
	  */
	public void uploadMultipartFile(MultipartFile[] files,String bucketKey) throws IOException{
		
		ObjectMetadata omd = new ObjectMetadata();
		
		for(int i=0; i<files.length; i++) {
			omd.setContentType(files[i].getContentType());
			omd.setContentLength(files[i].getSize());
			omd.setHeader("filename",files[i].getOriginalFilename());
			s3Client.putObject(new PutObjectRequest(bucketName+bucketKey,files[i].getOriginalFilename(),files[i].getInputStream(),omd));
		}
	}
	

	/**
	
	  * @Method Name : uploadQRcode
	  * @작성일 : 2020. 2. 17.
	  * @작성자 : Sangwon Hyun
	  * @Method 설명 : S3 buffered 이미지 업로드
	  * @param os
	  * @param imgName (저장하고 싶은 이미지이름)
	  * @param bucketKey (실제 저장할 경로)
	  * @throws IOException
	  */
	public void uploadBufferedImage(ByteArrayOutputStream os,String imgName,String bucketKey) throws IOException{
		byte[] buffer = os.toByteArray();
       		InputStream is = new ByteArrayInputStream(buffer);
		ObjectMetadata meta = new ObjectMetadata();
		meta.setContentLength(buffer.length);
		s3Client.putObject(new PutObjectRequest(bucketName+bucketKey,imgName,is,meta));
	}
	
}

 

5. Controller 구현

이미지 업로드는 AJAX로 처리를 했습니다.

/**
	
	  * @Method Name : uploadImages
	  * @작성일 : 2020. 1. 8.
	  * @작성자 : Sangwon Hyun
	  * @Method 설명 : AWS S3 이미지 다중 업로드
	  * @param file
	  * @return
	  * @throws Exception
	  */
	@PostMapping("/obj/img-put")
	public @ResponseBody String uploadImages(@RequestParam("files") MultipartFile[] files
	)throws Exception 
    {
		logger.debug("[ Call /obj/img-put - POST ]");
		logger.debug("====> Parameters      file length  : " + files.length);
	
    		String s3Path = "/images";
		awsService.uploadObject(files,s3Path);
		
		return "success";
	}