s3버킷 생성
버킷생성 눌러주고 체크한 부분만 신경써준다!
객체 소유권 ACL 활성화 시켜야함!
버킷생성후! 버킷클릭 -> 권한 -> 버킷정책 -> 편집 ( 버킷 ARN 복사)
-> 정책생성기
Generate Policy 까지하면 복사할 json이 나온다!
복사한걸 버킷정책에 붙여넣고 저장해주자!
IAM 사용자 생성
오른쪽위에 내 계정 누르고 -> 보안자격증명 누르고 -> 사용자 -> 사용자추가
그리고 다음 쭉쭉 누르고 넘어가면
Access Key와 Secret access key가 주어지는데 잘 저장한다 ( csv 파일로 저장 후 구글드라이브같은곳에 저장)
의존성 추가하기 ( build.gradle에 dependency 추가)
//s3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
applciation.yml
s3와 관련된 프로퍼티값들을 설정해준다.
spring:
servlet: # s3관련
multipart:
max-file-size: 20MB #파일하나의 최대크기
max-request-size: 100MB # 전송하려는 총 파일들의 크기
#s3관련
cloud:
aws:
s3:
bucket: 버켓이름
credentials: #IAM 키값들
access-key: 엑세스키값
secret-key: 시크릿키값
region:
static: ap-northeast-2 # 지역
auto: false
stack:
auto: false
application.properties나 새로운 properties 파일을 만들어 거기다가 설정해줘도된다.
application.yml과 application.properties의 차이?
application.properties
는 key-value 형식을 사용한다. (.점)을 이용하여 계층적 구조를 표시한다.
값을 지정할때 ${}를 이용하여 다른 환경변수의 값을 참조할 수 있다.
여러개의 properties파일을 만들어 이름별로 환경변수를 정리할 수있다
application.yml
계층적으로 보여줘서 보기가 깔끔하다.
YAML은 한 파일에서 다중 profile를 정의 할 수있다.
주의
application.yml과 application.properties를 동시에 사용하지않게 주의해야한다.
properties가 yml보다 늦게 로드되어 yml에서 설정한 환경변수 설정들이 덮어씌어질 수 있기때문이다.
자세히 알아보기 ->
https://newwisdom.tistory.com/m/89
https://recordsoflife.tistory.com/m/434
S3 설정 등록 -> AwsS3Config.java 생성
@Configuration
public class AwsS3Config {
@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 AmazonS3Client amazonS3() { //이부분은 AmazonS3Client로 수정(다른블로그 참고)
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
}
Service 파일 생성
@Slf4j
@RequiredArgsConstructor
@Service
public class AwsS3Service {
private final AmazonS3Client amazonS3Client;
@Value("${cloud.aws.s3.bucket}")
private String bucketName;
public List<String> uploadFileV1(List<MultipartFile> multipartFiles) throws BaseException {
List<String> result = new ArrayList<>(); //저장된 s3 upload url을 저장할 변수
for (int i = 0; i < multipartFiles.size(); i++) {
MultipartFile current_file = multipartFiles.get(i); //파일하나씩 가져옴.
String fileName = UUID.randomUUID().toString().substring(0,20); //파일이름은 uuid를 이용하여 랜덤으로 지정해서 넘긴다.
ObjectMetadata objectMetadata = new ObjectMetadata(); //오브젝트메타데이터 생성
objectMetadata.setContentType(current_file.getContentType()); //오브젝트 메타데이터에 파일의 컨텐트타입을 세팅
objectMetadata.setContentLength(current_file.getSize()); //사이즈 설정 No content length specified for stream data를 위함.
try (InputStream inputStream = current_file.getInputStream()) { //파일 업로드
amazonS3Client.putObject(new PutObjectRequest(bucketName, fileName, inputStream, objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (IOException e) {
throw new BaseException(FAIL_FILE_UPLOAD);
}
result.add(amazonS3Client.getUrl(bucketName, fileName).toString()); //url를 가져와서 리스트에 저장.
}
return result; //url 리스트를 리턴.
}
}
업로드 함수를 가지고있는 Service를 구성해준다.
여러장의 이미지를 받고싶어서 List<MultipartFile>로 구성하였고
S3에 저장될 파일이름은 UUID를 이용하여 랜덤으로 20가 되게 구성하였다.
중간에 오브젝트 메타데이터에 파일길이를 Set해주는 부분이있는데 그 부분을 까먹으면
- [WARN ] c.a.services.s3.AmazonS3Client:1714 - No content length specified for stream data. Stream contents will be buffered in memory and could result in out of memory errors.
이라는 오류가 발생한다.
오브젝트 메타데이터에 contentType, length 등을 담고
버킷이름,파일이름,인풋스트림(이미지), 오브젝트 메타데이터를 이용하여 업로드 해준다.
그 후 업로드한 이미지의 URL를 받아와 저장하고 리턴해준다.
Controller에서 업로드 사용
/**
* S3업로드 실험용 api
* */
@Transactional
@ResponseBody
@PostMapping("/upload")
public BaseResponse<PostUploadRes> uploadFiles (@RequestPart(value = "files")List<MultipartFile> multipartFiles)
{
try{
List<String> result_urls = awsS3Service.uploadFileV1(multipartFiles);
PostUploadRes postUploadRes = new PostUploadRes(result_urls);
return new BaseResponse<>(postUploadRes);
}catch (BaseException e)
{
e.printStackTrace();
return new BaseResponse<>(e.getStatus());
}
}
다음과 같이 @RequestPart를 이용하여 파일을 받는다. (s3에 저장된 url를 리턴하는 api)
포스트맨에서 Body에서 form-data를 선택
Key를 적는곳 오른쪽에 File로 꼭 선택해줘야한다.
파일명에 관해서 다른걸 추가하고 싶다면 또는 파일다운로드 관련
참고 블로그 확인
참고 + 추가적인내용
'aws' 카테고리의 다른 글
인텔리제이 - ec2연결 (remote host) (0) | 2022.10.09 |
---|
댓글