1. 버킷 생성
설정한 후 버킷을 생성해준다.
권한 탭 > 버킷 정책 > 편집
Principal은 *, Actions는 DeleteObject, GetObject, PutObject 를 선택해주고, ARN은 이전 페이지에 있던 ARN을 복사해서 붙여넣는다.
Add Statement를 클릭하면 Generate Policy를 통해 정책을 생성하자. 생성된 JSON 타입 정책을 이전 페이지에 붙여넣으면 된다.
CORS 설정하는 경우는 많지 않았지만, 그래도 혹시 모르니 미리 설정하기로 했다.
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"HEAD",
"GET",
"PUT",
"POST"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag"
]
}
]
2. IAM 사용자 생성 및 권한 부여
사용자 이름을 정해준다.
다음을 클릭하고, 직접 정책 연결을 선택하여 AmazonS3FullAccess 를 추가한다.
다음을 클릭하고, 사용자 생성을 해준다.
3. 액세스 키 생성
생성한 사용자 이름을 클릭 > 보안 자격 증명 탭 > 액세스 키 만들기 클릭
대안은 아무거나 선택해도 된다.
발급받은 Access Key와 Secret Access Key를 따로 저장해두거나, cvs 파일을 받아두길 바란다.
4. build.gradle 설정
aws s3를 사용하기 위해 build.gradle에 의존성을 추가하자.
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
5. application.yml 설정
필자는 외부에 공개되면 안되는 설정 정보는 application-secret.yml 과 같이 따로 관리하여 .gitignore에 추가했다.
사용하는 설정 파일에 다음과 같이 작성하자.
cloud:
aws:
credentials:
access-key: 액세스키 #IAM ACCESS_KEY
secret-key: 시크릿액세스키 #IAM SECRET_KEY
s3:
bucket: 버킷이름 #버킷 이름
region:
static: ap-northeast-2
stack:
auto: false
6. Config 클래스 추가
다음과 같이 설정파일을 추가해준다.
package com.team10.whatis.global.config;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
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 S3Config {
@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 AmazonS3 amazonS3Client() {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
}
7. Controller와 Service
컨트롤러에 다음과 같은 메서드를 작성해주었다. 본인 프로젝트에 맞게 작성해주면 된다.
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseDto<String> uploadImage(@RequestPart(value = "image") MultipartFile image) {
return postService.uploadImage(image);
}
서비스에는 다음과 같은 메서드를 작성해주었다. return값으로 업로드된 이미지의 url을 반환했다.
@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class PostService {
@Value("${cloud.aws.s3.bucket}")
private String bucket;
private final AmazonS3 amazonS3;
/**
* s3 이미지 업로드
*/
public String uploadImage(MultipartFile image) {
//중복된 이름 방지를 위한 UUID 붙이기
String fileName = UUID.randomUUID() + "-" + image.getOriginalFilename();
//메타 데이터 설정
ObjectMetadata objMeta = new ObjectMetadata();
objMeta.setContentType(image.getContentType());
objMeta.setContentLength(image.getSize());
try {
objMeta.setContentLength(image.getInputStream().available());
//s3에 파일 업로드
amazonS3.putObject(bucket, fileName, image.getInputStream(), objMeta);
} catch (IOException e) {
throw new IllegalArgumentException("이미지 업로드에 실패했습니다.");
}
return amazonS3.getUrl(bucket, fileName).toString();
}
}
PostMan에서 form-data로 요청을 보내고 확인해보면 s3 버킷에 정상적으로 업로드 된다.
'Spring' 카테고리의 다른 글
[Spring] @RequestParam으로 Enum 타입 매개변수 받기 (0) | 2023.05.15 |
---|---|
[Spring] @RequestPart 사용하여 MultipartFile과 Dto 함께 받기, Postman 테스트 (0) | 2023.05.14 |
[Spring] EC2 서버 실행 시, Web server failed to start. Port 8080 was aleady in use 해결 (0) | 2023.05.08 |
[Spring] EC2 Connection Time 지정 (0) | 2023.05.08 |
[Spring] SpringBoot EC2에서 AWS RDS MariaDB 연동 및 배포 (2) | 2023.05.08 |