Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.day_walk.backend.domain.image.controller;

import com.day_walk.backend.domain.image.service.ImageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
Expand All @@ -20,7 +21,7 @@ public class ImageController {

private final ImageService imageService;

// 파일 업로드 API
@Operation(summary = "이미지 업로드", description = "S3에 이미지를 저장 합니다.")
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Map<String, Object>> uploadImage(@RequestBody MultipartFile file) {

Expand All @@ -33,4 +34,18 @@ public ResponseEntity<Map<String, Object>> uploadImage(@RequestBody MultipartFil

return ResponseEntity.status(HttpStatus.OK).body(response);
}

@Operation(summary = "이미지 삭제", description = "S3에 저장된 이미지를 삭제합니다.")
@DeleteMapping
public ResponseEntity<Map<String, Object>> deleteImage(@RequestBody String imgUrl) {

boolean result = imageService.deleteImage(imgUrl);

Map<String, Object> response = new HashMap<>();
response.put("message", result ? "이미지 삭제 성공!" : "이미지 삭제 실패..");
response.put("success", result);

return ResponseEntity.status(HttpStatus.OK).body(response);
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.day_walk.backend.domain.image.service;

import com.day_walk.backend.global.error.CustomException;
import com.day_walk.backend.global.error.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.GetUrlRequest;

import java.net.URL;
import java.util.UUID;

@Service
Expand All @@ -18,26 +23,26 @@ public class ImageService {

private final S3Client s3Client;


public String uploadImage(MultipartFile multipartFile) {

if(multipartFile.isEmpty()) {
throw new CustomException(ErrorCode.IMAGE_NOT_FOUND);
}

try {
// S3에 저장될 고유한 파일 이름 생성
String randomName = UUID.randomUUID().toString();
String fileName = randomName + "_" + multipartFile.getOriginalFilename();

// S3 업로드 요청 객체 생성
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.contentType(multipartFile.getContentType())
.build();

// 파일 업로드
s3Client.putObject(putObjectRequest,
RequestBody.fromInputStream(multipartFile.getInputStream(), multipartFile.getSize())
);

// S3에서 해당 파일의 URL 가져오기
return s3Client.utilities().getUrl(GetUrlRequest.builder()
.bucket(bucketName)
.key(fileName)
Expand All @@ -47,4 +52,34 @@ public String uploadImage(MultipartFile multipartFile) {
throw new RuntimeException("S3 업로드 실패: " + e.getMessage(), e);
}
}

public boolean deleteImage(String imgUrl) {
if(imgUrl == null) {
throw new CustomException(ErrorCode.IMAGE_NOT_FOUND);
}
try {
imgUrl = imgUrl.replace("\"", "");
URL url = new URL(imgUrl);
String key = url.getPath().substring(1);
System.out.println("Key : " + key);

DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();

DeleteObjectResponse deleteResponse = s3Client.deleteObject(deleteObjectRequest);

if (deleteResponse.sdkHttpResponse().isSuccessful()) {
return true;
} else {
System.err.println("이미지 삭제 실패: " + key);
throw new CustomException(ErrorCode.IMAGE_DELETE_FAIL);
}

} catch (Exception e) {
throw new RuntimeException("S3 삭제 실패: " + e.getMessage(), e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public enum ErrorCode {
COURSE_LIKE_NOT_FOUND(HttpStatus.NOT_FOUND, false, "COURSE_LIKE_010", "코스 찜한 내역을 찾을 수 없습니다."),
COURSE_LIKE_IS_EXIST(HttpStatus.BAD_REQUEST, false, "COURSE_LIKE_030", "이미 찜한 코스입니다."),

PLACE_LIKE_NOT_FOUND(HttpStatus.NOT_FOUND, false, "PLACE_LIKE_010", "장소 찜 내역을 찾을 수 없습니다.");
PLACE_LIKE_NOT_FOUND(HttpStatus.NOT_FOUND, false, "PLACE_LIKE_010", "장소 찜 내역을 찾을 수 없습니다."),

IMAGE_NOT_FOUND(HttpStatus.NOT_FOUND, false, "IMAGE_010", "이미지를 불러올 수 없습니다."),
IMAGE_DELETE_FAIL(HttpStatus.BAD_REQUEST, false, "IMAGE_040", "이미지 삭제를 실패했습니다.");

private final HttpStatus httpStatus;
private final boolean success;
Expand Down