2023. 9. 6. 22:43ㆍSpring
개요
최근에 Spring 환경 프로젝트에서 S3로 파일을 업로드를 해야 하는 일이 있었다.
이전에는 org.springframework.cloud 라이브러리를 활용했는데, 상당 기능이 deplicate 되어 있었다.
따라서 io.awspring-s3 라이브러리를 활용했는데, 이전보다 훨씬 S3를 이용하는 것이 쉬웠다 세상 좋아졌네
위 라이브러리를 통한 S3 파일 업로드 구현 과정을 설명하고자 한다
전체 샘플 코드는 아래 링크로
https://github.com/phjppo0918/spring-io-awspring-s3-practice
0. 버킷 생성
이름 넣고, 리전 한국으로 설정하고, 퍼블릭 엑세스 차단 해제하고 시작하자
1. 라이브러리 추가
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.2")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3'
2. properties 설정
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
cloud:
aws:
credentials:
access-key: "asdf"
secret-key: "asdf"
s3:
bucket: "asdfasdf"
- multipart 용량 제한을 설정할 수 있다. default는 20MB이다.
- 본인의 지갑에 현금이 갑자기 꼴도 보기 싫다면, aws 키를 그대로 담은 채 push하여 전 세계로 IAM 계정을 널리 알리면 된다.
- S3.bucket는 필자가 직접 제작한 custom properties이다. Repository에서 bucket name 설정 시 사용한다.
3. 예시 Controller & Service
@RestController
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@RequestMapping("images")
public class ImageController {
ImageService imageService;
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public String create(@RequestPart MultipartFile file) {
return imageService.create(file);
}
}
@Service
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
@RequiredArgsConstructor
public class ImageService {
ImageRepository imageRepository;
public String create(MultipartFile file) {
return imageRepository.save(file);
}
}
@RequestPart를 통해서 MultiPartFile를 받아온다. List<MultiPartFile> 로 해서 다수개를 받을 수도 있다.
4. Repository 설정
@Repository
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class ImageRepository {
S3Template s3template;
String bucketName;
public ImageRepository(S3Template s3template,
@Value("${spring.cloud.aws.s3.bucket}") String bucketName) {
this.s3template = s3template;
this.bucketName = bucketName;
}
public String save(MultipartFile file) {
final S3Resource result = s3template.upload(bucketName, file.getOriginalFilename(), getInputStream(file));
return getUrl(result);
}
private InputStream getInputStream(MultipartFile file) {
try {
return file.getInputStream();
} catch (IOException e) {
throw new RuntimeException();
}
}
private String getUrl(S3Resource s3Resource) {
try {
return s3Resource.getURL().toString();
} catch (IOException e) {
throw new RuntimeException();
}
}
}
별도 설정 없이 간단하게 S3Template를 사용할 수 있다. 나때는 Client 직접 설정하고 별 난리를 다 했는데 세상 좋아졌다.
upload 시 file name에 확장자를 붙여서 저장하도록 하자. 안그러면 아래와 같이 쓰레기가 만들어진다.
참고로 파일 외에 store & read를 이용해서 json 형태로 객체 저장도 되는듯 하다(아래 참고 참조)
5. 엑세스 권한 설정
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1405592139000",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::버킷이름/*",
"arn:aws:s3:::버킷이름"
]
}
]
}
버킷 정책에 추가하면 된다.
6. 확인
파일 클릭하면 이미지가 나올 것이다.
참고
https://docs.awspring.io/spring-cloud-aws/docs/3.0.0-M1/reference/html/index.html
'Spring' 카테고리의 다른 글
spring 환경에서 redis pub-sub을 이용한 멀티 캐스팅 (0) | 2023.07.15 |
---|---|
Spring boot oauth2로 로그인하기 (0) | 2022.02.13 |
JWT, 그리고 OAuth (0) | 2022.02.11 |
Intellij 에서 Spring MVC 프로젝트(Gradle) 생성 (0) | 2022.01.28 |