순서 요약
1. S3 bucket 생성
2. IAM 사용자 -> 정책 추가
3. gradle에 dependency 추가, yml 설정, S3UploaderService 생성, api 추가
1. S3 bucket을 생성한다.
다음 링크로 이동 -> https://s3.console.aws.amazon.com/s3/get-started?region=ap-northeast-2
버킷 만들기로 이동 -> 버킷이름 리전 설정.
객체 소유권 활성화
퍼블릭 엑세스 차단 해제 (->정책 편집하기 위함. 정책 편집 후 다시 차단)
나머지 설정 그대로 버킷 생성
2. IAM 생성
사용자 추가
사용자 이름 작성, 엑세스 키 선택
기존 정책 직접 연결 -> amazonS3FullAccess 선택-> 나머지 단계 그대로 다음 이동 -> 사용자 생성
3 - 1. gradle에 dependency추가
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
3 - 2. yml 설정
#s3 설정
spring:
profiles:
group:
"local": "local, common"
"development": "development,common"
active: local
---
# 공통
spring:
config:
activate:
on-profile: "common"
servlet:
multipart:
max-file-size: 5GB
max-request-size: 5GB
cloud:
aws:
region:
static: ap-northeast-2
s3:
bucket: {버킷이름}
stack:
auto: false
credentials:
instance-profile: true
access-key: {엑세스키}
secret-key: {시크릿키}
logging:
level:
com.amazonaws.util.EC2MetadataUtils: error
---
# 로컬 환경
spring:
environment: "local"
config:
activate:
on-profile: "local"
file-dir: /src/main/resources/static/files/
---
# 배포 환경
spring:
environment: "development"
config:
activate:
on-profile: "development"
file-dir: /home/ec2-user/files/
common은 공통으로 적용되는 속성,
local과 developement로 나누어 로컬 환경과 배포환경 설정을 달리한다.
각각 파일이 저장되는 경로를 지정해준다.
cloud.aws 설정에서 버킷이름과 IAM 생성시 발급해주는 엑세스 키, 시크릿 키를 잘 입력해준다.
3-3. S3UploaderService
@Slf4j
@Service
@RequiredArgsConstructor
public class S3UploaderService {
// local, development 등 현재 프로파일
@Value("${spring.environment}")
private String environment;
// 파일이 저장되는 경로
@Value("${spring.file-dir}")
private String basicDir;
private String fileDir;
private final AmazonS3Client amazonS3Client;
/**
* 서버가 시작할 때 프로파일에 맞는 파일 경로를 설정해줌
*/
@PostConstruct
private void init(){
if(environment.equals("local")){
this.fileDir = System.getProperty("user.dir") + this.basicDir;
} else if(environment.equals("development")){
this.fileDir = this.basicDir;
}
}
public String upload(MultipartFile multipartFile, String bucket, String dirName) throws IOException {
File uploadFile = convert(multipartFile) // 파일 변환할 수 없으면 에러
.orElseThrow(() -> new IllegalArgumentException("error: MultipartFile -> File convert fail"));
return upload(uploadFile, bucket, dirName);
}
// S3로 파일 업로드하기
private String upload(File uploadFile, String bucket, String dirName) {
String fileName = dirName + "/" + UUID.randomUUID() + uploadFile.getName(); // S3에 저장된 파일 이름
String uploadImageUrl = putS3(uploadFile, bucket, fileName); // s3로 업로드
removeNewFile(uploadFile);
return uploadImageUrl;
}
// S3로 업로드
private String putS3(File uploadFile, String bucket, 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");
}
/**
* @param multipartFile
* 로컬에 파일 저장하기
*/
private Optional<File> convert(MultipartFile multipartFile) throws IOException {
if (multipartFile.isEmpty()) {
return Optional.empty();
}
String originalFilename = multipartFile.getOriginalFilename();
String storeFileName = createStoreFileName(originalFilename);
//파일 업로드
File file = new File(fileDir+storeFileName);
multipartFile.transferTo(file);
return Optional.of(file);
}
/**
* @description 파일 이름이 이미 업로드된 파일들과 겹치지 않게 UUID를 사용한다.
* @param originalFilename 원본 파일 이름
* @return 파일 이름
*/
private String createStoreFileName(String originalFilename) {
String ext = extractExt(originalFilename);
String uuid = UUID.randomUUID().toString();
return uuid + "." + ext;
}
/**
* @description 사용자가 업로드한 파일에서 확장자를 추출한다.
*
* @param originalFilename 원본 파일 이름
* @return 파일 확장자
*/
private String extractExt(String originalFilename) {
int pos = originalFilename.lastIndexOf(".");
return originalFilename.substring(pos + 1);
}
}
설명 생략
3-4. api 추가
@PostMapping("/image-upload")
@ResponseBody
public String imageUpload(@RequestPart("file") MultipartFile multipartFile) throws IOException {
return s3UploaderService.upload(multipartFile, "{버킷이름}", "image");
}
설명 생략
swagger로 통해 업로드 확인
파일을 선택하고 execute를 누르면
성공!
S3 bucket에 들어가서 확인해보면
파일이 잘 저장된다. pdf, png 둘 다 가능하다.
자세한 설명은 다음 링크 : https://jojoldu.tistory.com/300
'프로젝트 > 잇타' 카테고리의 다른 글
검색 필터링 기능 구현(스프링 + mysql + java) (0) | 2024.01.21 |
---|---|
리눅스(linux) 실행권한 (0) | 2022.12.04 |
branch 사용법 (0) | 2022.11.19 |
백엔드 소셜로그인 구현 - 최대한 간략하게 (0) | 2022.11.12 |