이전 글에서 이어집니다.
이전까지의 이슈사항이라 생각했던 것들을 해결했다.
1. 서비스 배포 시 유저들이 이미지 변경이 잦아지면 잦아질수록 S3에 이미지들이 많이 쌓이는 문제
(어짜피 이전 이미지들을 활용하지 않을 것이기 때문에 삭제 요망)
2. 용량 제한
- 이 부분은 아직 반밖에 해결 못했다. 프론트와 백단에서 용량 제한을 걸어놓았지만 예외처리 제어를 하지 못해서 용량 초과가 나는 부분에 대해 사용자에게 에러코드를 보여주고 있다. ExceptionHandle을 조금 더 익혀서 포스팅하도록 하겠다.
우선, 기존의 form action을 ajax로 처리하였다.
이제 유저가 이미지 변경 시 이미지를 view해주는 부분만 렌더링되어 보여질 것이다.
function imgUpload(file, idx){
var formData = new FormData();
formData.append("imgfile", file);
$.ajax({
type : "PUT",
url : "/users/img/"+idx,
processData : false,
contentType : false,
data : formData,
enctype : 'multipart/form-data',
success : function(msg){
if(msg.includes("실패")) alert(msg.split(":")[0]);
else user_img.src = msg;
},error : function(err){
console.log(err);
}
})
}
아래의 서비스로직도 수정했다.
원래 생각했던 것은, S3에 업로드된 해당 유저의 모든 이미지를 지우고 하나만 딱 남겨두게 하려고 했다.
하지만 AWS S3에서는 파일 삭제시 해당 파일의 Key값(디렉토리와 파일 이름인 것 같다)이 필요하여
알지 못하는 Key에 대해 삭제처리가 되지 않았다.
@Transactional
@Override
public boolean img_modify(MultipartFile imgfile, UserDTO dto) throws IOException {
if(!imgfile.isEmpty()) {
UserEntity user = userRepository.findByIdx(dto.getIdx()).get();
String url = "https://randomchatuni.s3.ap-northeast-2.amazonaws.com/";
String beforeImg = user.getImg()==null ? null : user.getImg().replace(url, "");
if(beforeImg != null) beforeImg = URLDecoder.decode(beforeImg, "UTF-8");
String serverFileName = s3Uploader.upload(imgfile, user.getId(), beforeImg);
dto.setImg(serverFileName);
user.setImg(serverFileName);
return true;
}
else return false;
}
https://URL/diehreo2/%EC%BA%A1%EC%B2%98.jpg
이미지 저장 시, 위와 같은 형태로 이미지가 저장되고 있었는데
여기서 S3가 요구하는 Key값은 디렉토리 + 파일명이기 때문에, 앞의 URL은 replace를 통해 없애주었고
정확한 파일명이 요구되기 때문에 디코딩을 통해 파일명을 가져왔다.
삭제를 위해 가져온 정보 또한 업로드를 수행하는 객체에 보내줬다.
마지막으로 업로더 객체 또한 수정했다.
private String upload(File uploadFile, String dirName, String beforeImg) {
if(beforeImg != null) removeS3(beforeImg);
String fileName = dirName + "/" + uploadFile.getName();
String uploadImageUrl = putS3(uploadFile, fileName);
removeNewFile(uploadFile);
return uploadImageUrl;
}
private void removeS3(String fileName) {
try {
amazonS3Client.deleteObject(bucket, fileName);
System.out.println("S3 Uploded file remove success.");
} catch (AmazonServiceException e) {
System.out.println("S3 Uploded file remove fail.");
System.err.println(e.getErrorMessage());
System.exit(1);
}
}
유저의 이미지가 없을 경우를 null로 두었고, 이전 이미지가 있을 경우 해당 이미지를 지우는 로직을 작성했고
해당 코드는 AWS 공식 문서의 AWS S3 Example에 자세히 나와있다.
삭제가 잘 된 모습이다
AWS S3 업로드, 삭제 관련은 이정도로 마쳐도 될 것 같다.
해당 기능 작업을 하면서 에러 핸들링에 대해 깊게 공부해 봐야겠다는 생각이 들었다.
에러 핸들링에 대해 공부를 빡세게 예외처리를 잘할 수 있게 성장해야겠다.
공부한 내용을 정리해서 포스팅 할 수 있도록 해야지
끝~
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!