오늘은 드디어 배포 전 날...!!!
서비스 잘 돌아가는지 확인 잘 하고 배포하면 되겠지???
했는데 바로 오전부터 에러가..!!! 프로필 사진 변경이 안된다는 것
엥...??? 분명 저번에 잘 됐던것 같은데.. 무슨 에러지❓❓❓
알아보니 프로필 사진을 설정하지 않고 다른 부분(비밀번호나 상태메시지)만 바꾸면 에러가 뜬다.
이게 무슨 에러여!!! 분명.. 됐을터인데....
일단 바로 코드 확인부터 드가자잉!
if (user.getProfilePic() != null){
String[] spliturl = user.getProfilePic().split("버킷 주소라 가립니당 ㅎㅎ");
s3Service.delete(spliturl[1]);
}
String name = s3Service.uploadToAWS(profileUpdateDto.getProfilePic());
String profilePic = "여기도 마찬가지!" + name;
String password = passwordEncoder.encode(profileUpdateDto.getPassword());
user.update(profileUpdateDto, password,profilePic);
}
}
원래 코드는 이렇게나 간단하게 되어있었다!!!
이 코드를 보면서 한참 생각하다 보니... 아... 저때도 프로필이 있는 경우는 변경이 되고 없을때는 안된다고 팀원들이랑 얘기했었던것 같은데..??? (근데 그걸 처리 안하고 넘어갔었다고?? ⬅️제정신인가???💢)
if (profileUpdateDto.getProfilePic() != null){
if (user.getProfilePic() == null){
String name = s3Service.uploadToAWS(profileUpdateDto.getProfilePic());
String profilePic = "주소가리기" + name;
String password = passwordEncoder.encode(profileUpdateDto.getPassword());
user.update(profileUpdateDto, password,profilePic);
}
if(user.getProfilePic().contains("kakaocdn")){
String name = s3Service.uploadToAWS(profileUpdateDto.getProfilePic());
String profilePic = "주소가리기2" + name;
String password = passwordEncoder.encode(profileUpdateDto.getPassword());
user.update(profileUpdateDto, password,profilePic);
}
if(user.getProfilePic() != null){
String[] spliturl = user.getProfilePic().split("주소가리기3");
s3Service.delete(spliturl[1]);
String name = s3Service.uploadToAWS(profileUpdateDto.getProfilePic());
String profilePic = "주소가리기4" + name;
String password = passwordEncoder.encode(profileUpdateDto.getPassword());
user.update(profileUpdateDto, password,profilePic);
}
} else {
String profilePic = user.getProfilePic();
String password = passwordEncoder.encode(profileUpdateDto.getPassword());
user.update(profileUpdateDto, password,profilePic);
}
이렇게 코드를 작성했다... 꽤 오래걸렸음.. ㅠㅠㅠ
처음에 작성했을때는 일반유저는 되는데 카카오 로그인 유저는 안되서 또 고치고
다음에는 카카오 유저는 되는데 일반유저는 안되고..
이제 둘 다 되는데 갑자기 WARN
이 뜨고... 휴... 처리해서 다행이당!
젤~ 처음에는 user.getProfilePic() != null
으로 판단했었는데 생각해보니 원래 아이디를 생성하면 기본으로 profilePic = null
이라서 아~! 그러면 수정을 할때 전달하는 사진이 있는지 판단해보자!!!! 해서 if (profileUpdateDto.getProfilePic() != null)
로 설정.
그 다음에 else 로 전달하는 파일이 없으면 그냥 원래 있는 null로 설정하고 나머지만 update 해줘!!
그리고 if (profileUpdateDto.getProfilePic() != null)
여기 안에서 또 조건을 걸어서
파일을 처리해주면 어떨까???
해서 if를 무려 3개나 작성...
- if (user.getProfilePic() == null)
- 프로필 사진이 null 이면(기본 이미지면) 그냥 바로 저장
- if(user.getProfilePic().contains("kakaocdn"))
- 프로필 사진 내용에 "kakaocdn" 라는 문자가 포함되면 무시하고 저장
(카카오에서 받아오는 사진 형식이 ~kakaocdn~ 라고 저장되고, S3에는 저장되지 않아서 그냥 저장하는 걸로 하면 된다, S3에서 삭제시킬 필요가 없음.)
- if(user.getProfilePic() != null)
- 마지막. 프로필 사진이 이미 설정 되어있다면, S3에서 파일을 찾아 삭제시키고
새로운 프로필 사진을 저장!!
이렇게 하면 프로필 사진이 잘 바뀌는 걸 볼 수 있다! (뿌듯😎)
No content length specified for stream data. Stream contents will be buffered in memory and could result in out of memory errors.
갑자기 이게 뜨길래 오잉 뭐징??? 했다... 알아보니
metadata로 contentLength를 설정하지 않으면 S3에 업로드는 되나, 다음과 같은 에러로그가 나온다.
라는 DOing님의 블로그를 찾을 수 있었다.
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(file.getContentType());
PutObjectRequest request = new PutObjectRequest(bucketName, key, file.getInputStream(), metadata);
request.withCannedAcl(CannedAccessControlList.PublicReadWrite); // 접근권한 체크
PutObjectResult result = s3Client.putObject(request);
return key;
이렇게 되어있고 metadata.setContentType
은 있으나 metadata.setContentLength
는 없음.
그리고 setContentLength
는 getInputStream
을 사용하는 것 같은데
PutObjectRequest request = new PutObjectRequest(bucketName, key, file.getInputStream(), metadata);
그냥 여기서 file.getInputStream()
으로 사용중이었다!!!
ObjectMetadata metadata = new ObjectMetadata();
byte[] bytes = IOUtils.toByteArray(file.getInputStream());
metadata.setContentLength(bytes.length);
metadata.setContentType(file.getContentType());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
PutObjectRequest request = new PutObjectRequest(bucketName, key, byteArrayInputStream, metadata);
request.withCannedAcl(CannedAccessControlList.PublicReadWrite); // 접근권한 체크
PutObjectResult result = s3Client.putObject(request);
return key;
이렇게 수정!
byte[] bytes = IOUtils.toByteArray(file.getInputStream());
metadata.setContentLength(bytes.length);
metadata.setContentType(file.getContentType());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
이 부분을 추가해주고
PutObjectRequest request = new PutObjectRequest(bucketName, key, byteArrayInputStream, metadata);
file.getInputStream()
을 사용하던 부분을 byteArrayInputStream,
으로 변경!!
이렇게 하면 setContentLength
가 있어서 더 이상은 위의 오류가 뜨지 않는다!!!
해~결!!😗
자 이제 배포 가보자고~!~!
배포 전날이 젤 무섭다. 폭풍전야