부트캠프 TIL
부트캠프 main project "My-Buddy" -S3 이미지 업로드, 삭제
sweet-po
2023. 12. 13. 15:58
시간이 많이 지났지만 그 때 당시에 고민하며 해결해보았던 S3 이미지 업로드 삭제 기능 구현에 대한 블로깅을 남겨본다.
S3와 연동하는 방식은 MultipartFile 업로드 방식을 사용하였으며
https://devlog-wjdrbs96.tistory.com/323
https://galid1.tistory.com/590
위 블로그들을 참조하였다.
이미지 확장자 제한 기능과 이미지 업로드, 삭제 기능을 구현하였다.
확장자, 이미지 크기 제한 기능은 다른 방법들로도 가능했던 것 같다.
@Slf4j
@RequiredArgsConstructor
@Service
public class S3StorageService implements StorageService {
@Value("${cloud.aws.s3.bucket}")
private String bucket;
private final AmazonS3 amazonS3;
@Override
public String storeImage(MultipartFile multipartFile) {
String fileExtension = getFileExtension(multipartFile.getOriginalFilename());
ArrayList<String> extensionList = new ArrayList<String>(List.of(".png",".jpg",".gif",".jpeg"));
if (!extensionList.contains(fileExtension)){
throw new StorageException("Wrong file extension(" + fileExtension + ")");
}
String s3FileName = UUID.randomUUID().toString().concat(fileExtension);
try {
if (multipartFile.isEmpty()) {
throw new StorageException("Failed to store a file");
}
InputStream fileInputStream = multipartFile.getInputStream();
ObjectMetadata objMeta = new ObjectMetadata();
objMeta.setContentLength(fileInputStream.available());
log.info("Store an image into the storage");
amazonS3.putObject(bucket, s3FileName, fileInputStream, objMeta);
fileInputStream.close();
} catch (IOException e) {
throw new StorageException("Failed to store a file", e);
}
return amazonS3.getUrl(bucket, s3FileName).toString();
}
public void deleteImage(String photoUrl) {
String fileName = photoUrl.substring(photoUrl.lastIndexOf("/")+1);
amazonS3.deleteObject(bucket, fileName);
}
private String getFileExtension(String fileName) {
try {
return fileName.substring(fileName.lastIndexOf("."));
} catch (StringIndexOutOfBoundsException e) {
throw new StorageException("Wrong file extension(" + fileName + ")");
}
}
}
당시에 이미지 업로드시 이미지 이름 중복을 방지하기 위해 랜덤 문자를 붙여주는 방식을 취했는데
String s3FileName = UUID.randomUUID().toString().concat(fileExtension);
이렇게 랜덤 문자를 붙여주다보니 삭제할 때 해당 파일 이름을 어떻게 알 수 있을지에 대한 고민이 생겼고
이미지 업로드시 bucket 저장 url에 파일 이름이 포함되어 있기 때문에 이미지와 기능상 연결되어 있는 엔티티 필드(멤버 프로필사진, 게시물 사진)에 url을 포함시켜 DB에 저장해두었고
해당 이미지 삭제가 필요할 때 url 주소를 가져와 이미지 이름 부분만 잘라서 사용하였다.
String fileName = photoUrl.substring(photoUrl.lastIndexOf("/")+1);
고민해결 기록 끝!