# S3 만드는 방법 및 IAM 설정 방법
예제를 쓰기 전 밑 설정들이 다 되어있어야 가능합니다.
# gradle 추가
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.0.1.RELEASE'
# application.properties 설정
- properties
cloud.aws.credentials.accessKey={accessKey}
cloud.aws.credentials.secretKey={secretKey}
cloud.aws.s3.bucket={버킷 이름}
cloud.aws.region.static=ap-northeast-2 (지역)
cloud.aws.stack.auto=false
- yml
cloud:
aws:
credentials:
accessKey: IAM 사용자 엑세스 키
secretKey: IAM 사용자 비밀 엑세스 키
s3:
bucket: 버킷 이름
region:
static: ap-northeast-2
stack:
auto: false
# AmazonS3Config.class 작성
@Configuration
public class AmazonS3Config {
@Value("${cloud.aws.credentials.accessKey}")
private String accessKey;
@Value("${cloud.aws.credentials.secretKey}")
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();
}
}
# controller
@ResponseBody
@RequestMapping("/common/fileUpload")
public String fileUpload(@RequestParam("file") MultipartFile file) {
return s3Uploader.upload(file, BOARD.getPath());
}
# S3 이미지 업로드 전체 로직
- 아마 주석으로 설명을 남겨 놓아서 문제는 없을꺼라고 생각이든다.
package com.sparta_spring.sparta_spring3.util;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.sparta_spring.sparta_spring3.dto.FileUploadResponse;
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;
import java.io.*;
import java.util.UUID;
import static com.sparta_spring.sparta_spring3.domain.resultType.FileUploadType.UBUNTU_BASE_PATH;
@Slf4j
@RequiredArgsConstructor
@Component
public class S3Uploader {
private final AmazonS3Client amazonS3Client;
private final AmazonS3 amazonS3;
@Value("${cloud.aws.s3.bucket}")
public String bucket; // S3 버킷 이름
/* MultipartFile와 path만 가지고 이미지 업로드 */
public String upload(MultipartFile uploadFile, String path) {
String imgName = path + makeFileName(uploadFile); //새로운 이름만 만든다.
File imageFile = multipartFileToFileWithUpload(uploadFile); //S3에는 File 타입만 사용할 수 있어서 변환하는 과정
String uploadImageUrl = putS3(imageFile, imgName); //이미지 S3에 업로드 uploadImageUrl는 업로드하고 받은 url
removeNewFile(imageFile); //multipartFileToFileWithUpload() 이 과정에서 파일이 생성되었는데 삭제하는 로직
return new FileUploadResponse(uploadImageUrl).getUrl(); //S3에서 받은 Url를 가공하는 로직
}
// S3로 업로드
private String putS3(File uploadFile, String fileName) {
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile) //bucket이름, file이름, file를 인자로 주어 업로드
.withCannedAcl(CannedAccessControlList.PublicRead));
return amazonS3Client.getUrl(bucket, fileName).toString(); //s3에서 저장한 url 찾아오는 로직
}
// 로컬에 저장된 이미지 지우기
private void removeNewFile(File targetFile) {
if (targetFile == null) {
return;
}
if (targetFile.delete()) {
log.info("파일이 삭제되었습니다.");
return;
}
log.info("파일 삭제 실패");
}
/* S3에서 이미지 찾기 */
public S3Object selectImage(String path, String imageName) {
S3Object s3Object = null;
try {
s3Object = amazonS3.getObject(new GetObjectRequest(bucket, path + imageName.substring(imageName.lastIndexOf("/") + 1)));
} catch (Exception e) {
log.info(e.getMessage());
}
return s3Object;
}
/* 이미지 삭제 */
public void fileDelete(String imageNameWithPath) {
try {
amazonS3.deleteObject(bucket, imageNameWithPath);
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
}
}
/* 같은 이름은 저장이 되지 않고 업데이트가 되므로 이름을 고유하게 바꿔주는 작업*/
public String makeFileName(MultipartFile attcFile) {
String attcFileNm = UUID.randomUUID().toString().replaceAll("-", "");
String attcFileOriNm = attcFile.getOriginalFilename();
String attcFileOriExt = fileExtCheck(attcFileOriNm.substring(attcFileOriNm.lastIndexOf(".")));
return attcFileNm + attcFileOriExt;
}
/* 확장자 체크로직 */
public String fileExtCheck(String originalFileExtension) {
originalFileExtension = originalFileExtension.toLowerCase();
if (originalFileExtension.equals(".jpg") || originalFileExtension.equals(".gif")
|| originalFileExtension.equals(".png") || originalFileExtension.equals(".jpeg")
|| originalFileExtension.equals(".bmp")) {
return originalFileExtension;
}
throw new RuntimeException(originalFileExtension + "는 지원하지 않습니다.");
}
/* S3에는 File 타입만 사용할 수 있어서 변환하는 과정 */
public File multipartFileToFileWithUpload(MultipartFile uploadFile) {
File file = null;
FileOutputStream fos = null;
try {
file = imageUploadToSever(uploadFile);
file.createNewFile();
fos = new FileOutputStream(file);
fos.write(uploadFile.getBytes());
} catch (Exception e) {
throw new RuntimeException("S3Uploader 121 에러" + e.getMessage());
} finally {
close(fos);
}
return file;
}
/* S3에는 File 타입만 사용할 수 있어서 변환하는 과정 */
public void close(FileOutputStream fos) {
if (fos == null)
return;
try {
fos.close();
} catch (Exception e) {
throw new RuntimeException("S3Uploader 137 에러" + e.getMessage());
}
}
/* 서버에 또는 로컬에 파일 업로드하는 작업 */
public File imageUploadToSever(MultipartFile uploadFile) {
String os = System.getProperty("os.name").toLowerCase();
if (os.startsWith("windows")) {
return new File(new File("").getAbsolutePath() + "\\" + uploadFile.getOriginalFilename());
}
File file = new File("/home/ubuntu");
if (!file.exists()) {
file.mkdirs();
}
return new File("/home/ubuntu" + "/" + uploadFile.getOriginalFilename());
}
}
'몰아 넣기' 카테고리의 다른 글
[Java/Spring] Spring Boot 메일 발송하기(Google SMTP With thymeleaf) (0) | 2022.07.18 |
---|---|
[java8] 자바 Stream의 foreach 와 for-loop에 대해서 (0) | 2022.07.14 |
[java/spring] Enum변수를 json으로 변환하여 Enum 값 전달하기 (0) | 2022.07.10 |
[java/spring] JPA timeStamp format 예제 (0) | 2022.07.10 |
[java/spring] try - catch - finally 보기좋게 작성하는 예제 또는 좋은 질문과 답변들 (0) | 2022.07.10 |