23.03.15 S3 이미지 수정삭제 구현!

Kuno17·2023년 3월 15일
0

TIL/WIL

목록 보기
26/38
post-thumbnail

S3에 저장된 데이터 수정,삭제 구현

오늘은 프로젝트에서 Post(게시글)을 수정할 때 기존에 저장되어 있는 이미지 리스트를 변경,삭제 하는 API를 구현했다.

수정의 조건에는 다음과 같은 시나리오가 예상되었다.

  1. 기존의 이미지에서 변경된 파일을 감지할 수 있는가? -> 현재로서는 불가
  2. 그렇다면 기존의 이미지를 모두 삭제한다 (DB와 S3모두 삭제한다)
  3. S3의 파일을 어떻게 찾아서 삭제할것인가?
  4. S3Service.java에 S3에 등록한 파일을 삭제하는 로직을 구현한다.

우와 같은 순서로 만들 수 있다면 처음으로 구현해야할 메서드는 S3에 있는 데이터를 지워주는 서드이다.

기존 S3Service.java에 추가해줄 수 있다.
여기서 사실 생각보다 파일이 저장되는 이름(url을 저장)을 주의깊게 살펴보아야 했다.

//key네임을 통해 S3에 등록된 파일을 제거
    public void deleteFile(String url) {
        String key = extractKeyFromUrl(url);
        try {
            s3Client.deleteObject(bucket, key);
        } catch (AmazonServiceException e) {
            throw new CustomException(Error.FAIL_S3_DELETE);
        }
    }
    
    // URL에서 파일 키 추출
    private String extractKeyFromUrl(String url) {
        String prefix = "https://s3." + region + ".amazonaws.com/" + bucket + "/";
        if (!url.startsWith(prefix)) {
            throw new CustomException(Error.FAIL_S3_DELETE);
        }
        return url.substring(prefix.length());
    }

핵심은?

중요한 부분은 String prefix = "https://s3." + region + ".amazonaws.com/" + bucket + "/";이부분 이다.

resion = S3 버킷이 등록된 지역.
bucket = 버킷의 이름.

현재 S3파일이 DB에 저장된되는 이름은 다음과 같다(Service 로직에 따라 다를 수 있음!!!)
https://s3.ap-northeast-2.amazonaws.com/kunon-clean-project/post/image/4cfa2cce-6574-49b0-8e40-1bcb42075a95.jpeg
이런 방식으로 이름이 저장된다.

해석해보자

현재 저장된 파일이름의 구조는
"https://s3." + region + ".amazonaws.com/" + bucket + "/"+저장경로+파일이름 으로 볼 수 있다.
여기서 필요한 부분은 바로 저장경로+파일이름이다.

extractKeyFromUrl 메서드는 데이터 베이스에 저장된 파일의 이름에서 S3파일의 key를 추출한다.

즉 preFix부분을 파일의 이름에서 제거하게 된다면
-> post/image/4cfa2cce-6574-49b0-8e40-1bcb42075a95.jpeg 이 부분만 남게된다.
이 key를 s3Client.deleteObject(bucket, key) 에 버킷이름과 함께 전달해서 제거하는 방법이다.

이외에도 파일을 제거하는 방법은 여러가지가 있을것으로 생각되나 내가 생각할 수 있던 방법은 이러한 방법이 떠오른것...

왜 어려웠던가?

처음에 데이터가 저장되는 이름을 자세하게 살펴보지 않고 다른 참조문서를 계속 봤는대
사실상 파일이름이 만들어지는 구조가 조금씩 달랐다.
다른 개발자분들이 구현할 때 만들어지는 파일이름의 순서가 달라 preFix구조가 다르게 만들어졌는데 이를 참조해서 내 코드에 적용하려하니 무한한 예외를 만날 수 밖에 없었다....
즉 파일이름을 만드는 로직에 따라 다르게 설정해 줄 필요가 있었다.

메서드에 적용!

Post를 업데이트 하는 메서드에서

            for (PostImage postImage : post.getImage()) {
                s3Service.deleteFile(postImage.getImage());
                postImageRepository.delete(postImage);
            }

이미지는 리스트이므로 iter를 사용해서 하나씩 뽑아서 S3와 DB에서 제거해준다.
S3에서도 말끔히 삭제되고!!
DB에서도 말끔히 삭제한 것을 확인.

profile
자바 스터디 정리 - 하단 홈 버튼 참조.

0개의 댓글