✨ 실시간으로 db와 실제파일이 이미지가 교체되고, 삭제되는 게 목표!
FormData
웹 애플리케이션에서 폼 데이터를 쉽게 생성하고 제어하기 위한 JavaScript의 내장 객체로 주로 HTTP POST 요청을 보낼 때 사용
public UserEntity fileHandler(MultipartFile file, String userEmail) throws Exception {
// 현재 작업경로의 절대경로
// File.separator (/)
String absolutePath = new File("").getAbsolutePath() + File.separator;
// 파일 저장 위치
String path = "src" + File.separator + "main" + File.separator + "resources" + File.separator + "static"
+ File.separator + "images" + File.separator + "userImg";
File userImg = new File(path);
if (!userImg.exists()) {
// 폴더없으면 생성
userImg.mkdirs();
}
if (!file.isEmpty()) {
// 파일이 비어있지 않으면
String contentType = file.getContentType();
String originalFileExtension;
// 타입에 따른 확장자 결정
if (ObjectUtils.isEmpty(contentType)) {
// 타입 없으면 null
return null;
} else {
if (contentType.contains("image/jpeg")) {
originalFileExtension = ".jpg";
} else if (contentType.contains("image/png")) {
originalFileExtension = ".png";
} else {
return null;
}
}
// 파일저장 이름
String originalFileName = file.getOriginalFilename();
// 확장자를 제외한 파일 이름과 확장자 추출
int lastIndex = originalFileName.lastIndexOf('.');
String fileName = originalFileName.substring(0, lastIndex);
String userImgName = fileName + System.nanoTime() + originalFileExtension;
// 파일 저장
userImg = new File(absolutePath + path + File.separator + userImgName);
System.out.println("파일 저장경로:" + absolutePath + path + File.separator + userImgName);
file.transferTo(userImg);
// 새로운 UserEntity 생성 및 파일 경로 전달 (db 저장에 사용)
UserEntity userEntity = new UserEntity();
userEntity.setUserProfile(path + File.separator + userImgName); // 실제 저장된 위치
return userEntity;
}
return null;
}
public ResponseEntity<String> deleteUserImg(String userEmail) {
Optional<UserEntity> userOptional = userRepository.findByUserEmail(userEmail);
if (userOptional.isPresent()) {
// 유저 정보가 있으면
UserEntity userEntity = userOptional.get();
try {
File imageFile = new File(userEntity.getUserProfile());
if (imageFile.exists()) {
// 파일이 존재하면 삭제
System.out.println("파일 존재함");
if (imageFile.delete()) { // 파일삭제
// db 삭제
userEntity.setUserProfile(null);
userRepository.save(userEntity);
return ResponseEntity.ok("이미지 삭제 성공");
} else {
// 파일 삭제 실패 시 오류 메시지 반환
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("이미지 파일 삭제 실패");
}
} else {
// 파일이 존재하지 않으면
return ResponseEntity.ok("이미지 파일이 이미 존재하지 않습니다.");
}
} catch (Exception e) {
// 파일 처리 실패 시 에러 메시지 반환
System.err.println(e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("이미지 삭제 오류");
}
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(userEmail + " 해당 이메일을 가진 사용자를 찾을 수 없습니다");
}
}
arraybuffer
바이트 단위로 데이터를 다룰 때 사용되는 버퍼로, 이진 데이터를 효율적으로 다룰 수 있도록 해줌 (주로 이미지, 오디오, 비디오 등의 바이너리 데이터를 다룰 때 사용)
Blob
Binary Large Object의 약자로, 이진 대형 객체
URL.createObjectURL()
주어진 객체나 데이터를 나타내는 URL을 생성하는 메서드로 이 URL은 브라우저 세션 동안만 유효하며, 해당 객체나 데이터에 대한 임시 URL을 생성
public byte[] getUserProfileImage(String userEmail) throws IOException {
System.out.println("getUserProfileImage 실행");
Optional<UserEntity> userOptional = userRepository.findByUserEmail(userEmail);
if (userOptional.isPresent()) {
UserEntity userEntity = userOptional.get();
String profileImagePath = userEntity.getUserProfile();
System.out.println("profileImagePath: " + profileImagePath);
// 프로필 이미지 경로가 null이 아니고 빈 문자열이 아닌 경우에만 이미지를 읽어옴
if (!StringUtils.isEmpty(profileImagePath)) {
Path imagePath = Paths.get(profileImagePath);
System.out.println("imagePath: " + imagePath);
if (Files.exists(imagePath)) {
// 파일이 존재하는 경우에만 읽어옴
return Files.readAllBytes(imagePath);
} else {
System.out.println("파일이 존재하지 않습니다.");
}
} else {
System.out.println("프로필 이미지 경로가 비어 있습니다.");
}
} else {
System.out.println("해당 유저가 존재하지 않습니다.");
}
// 만약 프로필 이미지를 찾을 수 없는 경우 빈 바이트 배열 반환
return new byte[0];
}
이미지 변경, 변경 해도 문제없고 삭제해도 잘 되는 걸 볼 수 있다.
*db와 파일도 실시간으로 잘 지워짐!
항상 스프링부트에서 이미지만 다뤄봤지 리액트에서 다뤄보긴 처음이라 어려웠다
이곳저곳 찾아보았지만 내가 원하는 실시간 교체 형식은 잘 없어서 이렇게 해보았는데, 이게 올바른 코드인지는 모르겠다.
여전히 프론트에서 백으로 데이터 주고 받기는 어렵고, 생소해서 전달방식에 대한 공부가 더 필요하고 절실히 느꼈다.