Spring

AWS S3 (이미지 다운로드 에러)

josolha 2023. 11. 20. 20:38
문제사항

 

프로젝트 진행하면서 이미지를 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-Typeimage/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 타입을 설정하는 것은 브라우저가 파일을 이미지로 인식하고 화면에 바로 표시하도록 하는 데

중요한 역할은 한다!!