util 폴더 안에 있는 AwsS3Utils 참고
이미지 등록
AwsS3Utils 클래스 안의 uploadImageToFolder 메서드를 사용
uploadImageToFolder 메서드 안에서 uploadImage 메서드를 호출해서 사용
// 특정 폴더에 이미지를 S3에 업로드하는 메서드
public String uploadImageToFolder(String folderName, Long id, MultipartFile file) throws IOException {
String fileName = folderName + "/" + id + "/" + UUID.randomUUID() + getFileExtension(file.getOriginalFilename());
// S3에 이미지 업로드
uploadImage(fileName, file);
// 업로드된 이미지 URL 반환
String imageUrl = getImageUrl(fileName);
// 성공적으로 저장된 경우 로그 출력
log.info("Uploaded image to S3: {}", imageUrl);
return imageUrl; // 업로드된 이미지 URL 반환
}
// getBytes와 fromInputStream()의 차이 공부
private void uploadImage(String fileName, MultipartFile file) {
try {
// S3에 업로드할 객체 요청을 생성
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName) // 업로드할 S3 버킷의 이름
.key(fileName) // S3에서의 파일 이름 (경로 포함)
.contentType(file.getContentType()) // 파일의 콘텐츠 타입 (예: image/jpeg)
.build();
// s3에 파일 업로드
s3Client.putObject(putObjectRequest,
RequestBody.fromInputStream(file.getInputStream(), file.getSize()) // InputStream으로부터 RequestBody를 생성, 실제 파일 데이터 포함
);
log.info("Uploaded image: {}", fileName);
} catch (IOException e) {
log.error("Error uploading image: {}", fileName, e);
throw new RuntimeException("Error uploading file: " + fileName, e);
}
}
S3에 이미지를 올리려면 filename이 필요함
S3 url : https://carrots-bucket.s3.ap-northeast-2.amazonaws.com/room/1/257890f7-73c7-4a76-962e-0191137c1311.jpg 위의 url에서는 아래 값이 filename에 해당
room/1/257890f7-73c7-4a76-962e-0191137c1311.jpg
필자는 S3 버킷 내에서 room폴더 안에 roomId폴더 안에 roomId에 해당하는 이미지들을 넣고 싶어서 filename을 아래처럼 지정함
String fileName = folderName + "/" + id + "/" + UUID.randomUUID() + getFileExtension(file.getOriginalFilename());
사용 예시
AccommodationImageService의 saveAccommodationImages 메서드
사용 부분:
// S3에 이미지 업로드
private String uploadImageToS3(Long accommodationId, MultipartFile image) throws IOException {
// AwsS3Utils 사용 부분
return awsS3Utils.uploadImageToFolder(IMAGE_FOLDER, accommodationId, image);
}
IMAGE_FOLDER는 해당 서비스 내에서 내가 임의로 지정해 주었음 (다른 분들은 바꾸시면 됩니다~)
private static final String IMAGE_FOLDER = "room";
그리고 accommodationId는 AccommodationImageService의 매개변수로 넘겨받았음
이미지 삭제
AwsS3Utils의 deleteImageFromUrl 메서드 참고
// 폴더로 만든 경우
public void deleteImageFromUrl(String url) throws IOException {
// URL에서 파일 경로 추출
String filePath = extractFilePathFromUrl(url);
// S3에서 객체 삭제 요청 생성
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
.bucket(bucketName) // 버킷 이름
.key(filePath) // 파일 경로
.build();
try {
s3Client.deleteObject(deleteObjectRequest); // S3에서 객체 삭제
log.info("Deleted image: {}", filePath); // 삭제 성공 로그
} catch (SdkException e) {
log.error("Error deleting file from S3: {}", filePath, e); // 삭제 실패 로그
throw new IOException("Error deleting file from S3: " + filePath, e); // 예외 발생
}
}
파일 경로를 받아와야 하기 때문에 extractFilePathFromUrl을 사용해 파일 경로 추출
private String extractFilePathFromUrl(String S3url) {
// URL을 슬래시('/')로 분리
String[] parts = S3url.split("/");
// room/42/와 파일 이름을 결합
return parts[parts.length - 3] + "/" + parts[parts.length - 2] + "/" + parts[parts.length - 1];
}
위의 코드가
이 url에서
room/1/257890f7-73c7-4a76-962e-0191137c1311.jpg
만 추출하는 코드
사용 예시
AccommodationImageService의 deleteExistingImages 메서드
// 기존 이미지 삭제 ( 메타 데이터 삭제 + s3 이미지 삭제)
private void deleteExistingImages(List<String> existingImageUrls) throws IOException {
if (existingImageUrls != null && !existingImageUrls.isEmpty()) {
for (String imageUrl : existingImageUrls) {
// 데이터베이스에서 이미지 메타데이터 삭제
deleteImageMetadata(imageUrl);
// S3에서 이미지 삭제 (AwsS3Utils 사용 부분)
awsS3Utils.deleteImageFromUrl(imageUrl);
log.info("Deleted image from S3: {}", imageUrl); // 삭제 로그 추가
}
}
}
필자는 업데이트 시 기존 이미지 삭제할때 사용함
controller를 통해 기존 이미지들이 담긴 url을 리스트로 받아오고(existingImageUrls) for문 돌려 삭제함
'[carrot-moa] 파이널 프로젝트' 카테고리의 다른 글
[Spring/Spring Boot] @ModelAttribute과 Model (0) | 2024.10.03 |
---|---|
[JAVA/Spring boot] Jasypt를 이용해서 암호화하기 (0) | 2024.09.28 |