AWS S3 (이미지 다운로드 에러)
문제사항
프로젝트 진행하면서 이미지를 s3 버킷에 등록을 했는데
AWS 로그인후 직접 S3 객체에 들어가서 URL을 복사해서 브라우져에서 여는 순간 계속 이미지는 안보이고
파일이 다운로드가 되는 현상을 마주하게 되었다
(임의로 내 이력서 사진을 올렸는데 내 사진을 계속 다운받고 있다는..ㅎㅎ)
private String uploadImageToS3(MultipartFile file) {
try {
String directoryPath = "boards/"; // S3 내의 저장하고 싶은 디렉토리 경로
String fileName = generateUniqueFileName(file.getOriginalFilename());
String key = directoryPath + fileName; // S3에 저장될 전체 파일 경로와 이름
// S3에 업로드할 객체 생성 요청
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.acl("public-read") // public-read 권한으로 설정
.build();
// S3에 파일 업로드 실행
s3Client.putObject(putObjectRequest, software.amazon.awssdk.core.sync.RequestBody.fromInputStream(file.getInputStream(), file.getSize()));
// 생성된 파일의 URL을 반환합니다.
return getFileUrl(key);
} catch (Exception e) {
throw new RuntimeException("S3 파일 등록이 실패했습니다.", e);
}
}
문제원인
찾아봣더니.. Content-Type이 올바르게 설정되지 않았기 때문에 발생한다고 한다.
웹 브라우저는 URL을 통해 파일을 불러올 때 Content-Type 헤더를 참조하여 파일을 어떻게 처리할지 결정하는데
이미지 파일의 경우, Content-Type이 image/jpeg, image/png 등과 같이 적절하게 설정되어야 브라우저가 해당 파일을 이미지로 인식하고 표시한다.
현재 위에 코드에서는 S3에 파일을 업로드할 때 Content-Type을 설정하는 부분이 없다.
이를 해결하기 위해서는 파일을 S3에 업로드하기 전에 파일의 MIME 타입을 결정하고, 이를 PutObjectRequest에 포함시켜야 한다.
해결
private String uploadImageToS3(MultipartFile file) {
try {
String directoryPath = "boards/"; // S3 내의 저장하고 싶은 디렉토리 경로
String fileName = generateUniqueFileName(file.getOriginalFilename());
String key = directoryPath + fileName; // S3에 저장될 전체 파일 경로와 이름
// 파일의 MIME 타입을 결정
String mimeType = file.getContentType();
// S3에 업로드할 객체 생성 요청
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.acl("public-read") // public-read 권한으로 설정
.contentType(mimeType) // 여기에 MIME 타입을 설정
.build();
// S3에 파일 업로드 실행
s3Client.putObject(putObjectRequest, software.amazon.awssdk.core.sync.RequestBody.fromInputStream(file.getInputStream(), file.getSize()));
// 생성된 파일의 URL을 반환합니다.
return getFileUrl(key);
} catch (Exception e) {
throw new RuntimeException("S3 파일 등록이 실패했습니다.", e);
}
}
String mimeType = file.getContentType(); 이 코드는 업로드하는 파일의 MIME 타입을 가져오는 것을 의미한다.
MIME 타입은 인터넷에서 파일의 형식을 식별하는 데 사용되는 표준이다.
(내가 JPEG 이미지를 업로드 했기 때문에 , Content-Type 헤더는 image/jpeg로 설정된다)
예를 들어, 이미지 파일의 경우 JPEG 형식은 image/jpeg, PNG 형식은 image/png 같은 MIME 타입을 가진다.
웹 브라우저는 URL을 통해 파일을 불러올 때 이 MIME 타입을 참조하여 파일을 어떻게 처리할지 결정한다.
만약 파일의 MIME 타입이 image/jpeg나 image/png 같은 이미지 형식으로 설정되어 있다면, 브라우저는 해당 파일을 이미지로 인식하고 화면에 직접 표시한다.
반면, MIME 타입이 설정되어 있지 않거나 잘못된 형식으로 설정되어 있다면, 브라우저는 파일을 다운로드해야 하는 것으로 판단할 수 있다.
따라서 S3에 파일을 업로드할 때 Content-Type 헤더에 이 MIME 타입을 설정하면, S3에서 파일을 제공할 때 이 정보를 사용하여 파일을 올바르게 제공한다.
결론
이미지 파일을 업로드할 때 올바른 MIME 타입을 설정하는 것은 브라우저가 파일을 이미지로 인식하고 화면에 바로 표시하도록 하는 데
중요한 역할은 한다!!