From dfde7ffa2027eed660aa628a9516b04ea2c36eee Mon Sep 17 00:00:00 2001 From: Kiara <80676180+2020147542@users.noreply.github.com> Date: Sun, 2 Feb 2025 14:23:34 +0900 Subject: [PATCH] =?UTF-8?q?[Refactor]=20fileUpload=EC=8B=9C=20image?= =?UTF-8?q?=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20=EB=B6=84=EA=B8=B0=20(#102)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codeplay/controller/FileController.java | 27 +++++------ .../umc/codeplay/domain/enums/FileType.java | 39 ++++++++++++++++ .../umc/codeplay/dto/FileResponseDTO.java | 7 +-- .../umc/codeplay/service/FileService.java | 45 ++++++------------- 4 files changed, 64 insertions(+), 54 deletions(-) create mode 100644 src/main/java/umc/codeplay/domain/enums/FileType.java diff --git a/src/main/java/umc/codeplay/controller/FileController.java b/src/main/java/umc/codeplay/controller/FileController.java index 1756614..76877af 100644 --- a/src/main/java/umc/codeplay/controller/FileController.java +++ b/src/main/java/umc/codeplay/controller/FileController.java @@ -1,12 +1,16 @@ package umc.codeplay.controller; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import lombok.RequiredArgsConstructor; import io.swagger.v3.oas.annotations.Operation; import umc.codeplay.apiPayLoad.ApiResponse; +import umc.codeplay.domain.enums.FileType; import umc.codeplay.dto.FileResponseDTO; import umc.codeplay.service.FileService; @@ -19,31 +23,20 @@ public class FileController { private final FileService fileService; - @Operation( - summary = "Download용 Presigned URL 생성", - description = "다운로드를 위한 Presigned URL 생성 - 유효시간 존재") - @GetMapping("/download") - public ApiResponse getUrl( - @RequestParam(value = "musicId") Long musicId) { - String downloadUrl = fileService.generateGetPresignedUrl(musicId); - FileResponseDTO.DownloadFile result = new FileResponseDTO.DownloadFile(downloadUrl); - return ApiResponse.onSuccess(result); - } - @Operation( summary = "Upload용 Presigned URL 생성", description = "업로드를 위한 Presigned URL 생성 - 유효시간 존재") @PostMapping("/upload") public ApiResponse generateUrl( + @RequestParam(value = "fileType") FileType fileType, @RequestParam(value = "fileName") String fileName) { String username = SecurityContextHolder.getContext().getAuthentication().getName(); - String newFileName = buildFilename(fileName); - System.out.println(newFileName); - Long musicId = fileService.uploadMusic(newFileName, username); + String newFileName = fileType.getFolderName() + buildFilename(fileName); + Long id = fileType.processUpload(fileService, newFileName, username); String uploadUrl = fileService.generatePutPresignedUrl(newFileName); - FileResponseDTO.UploadFile result = new FileResponseDTO.UploadFile(uploadUrl, musicId); - return ApiResponse.onSuccess(result); + + return ApiResponse.onSuccess(fileType.createResponse(uploadUrl, id)); } } diff --git a/src/main/java/umc/codeplay/domain/enums/FileType.java b/src/main/java/umc/codeplay/domain/enums/FileType.java new file mode 100644 index 0000000..4bbff7f --- /dev/null +++ b/src/main/java/umc/codeplay/domain/enums/FileType.java @@ -0,0 +1,39 @@ +package umc.codeplay.domain.enums; + +import umc.codeplay.dto.FileResponseDTO; +import umc.codeplay.service.FileService; + +public enum FileType { + AUDIO { + public String getFolderName() { + return "requestFiles/"; + } + + public Long processUpload(FileService fileService, String fileName, String username) { + return fileService.uploadMusic(fileName, username); + } + + public FileResponseDTO.UploadFile createResponse(String uploadUrl, Long id) { + return new FileResponseDTO.UploadFile(uploadUrl, id, null); + } + }, + IMAGE { + public String getFolderName() { + return "profileImgs/"; + } + + public Long processUpload(FileService fileService, String fileName, String username) { + return fileService.uploadProfile(fileName, username); + } + + public FileResponseDTO.UploadFile createResponse(String uploadUrl, Long id) { + return new FileResponseDTO.UploadFile(uploadUrl, null, id); + } + }; + + public abstract String getFolderName(); + + public abstract Long processUpload(FileService fileService, String fileName, String username); + + public abstract FileResponseDTO.UploadFile createResponse(String uploadUrl, Long id); +} diff --git a/src/main/java/umc/codeplay/dto/FileResponseDTO.java b/src/main/java/umc/codeplay/dto/FileResponseDTO.java index 3fd5f41..8d79620 100644 --- a/src/main/java/umc/codeplay/dto/FileResponseDTO.java +++ b/src/main/java/umc/codeplay/dto/FileResponseDTO.java @@ -5,16 +5,11 @@ public class FileResponseDTO { - @Getter - @AllArgsConstructor - public static class DownloadFile { - private String downloadS3Url; - } - @Getter @AllArgsConstructor public static class UploadFile { private String uploadS3Url; private Long musicId; + private Long memberId; } } diff --git a/src/main/java/umc/codeplay/service/FileService.java b/src/main/java/umc/codeplay/service/FileService.java index 5a438b9..93a3af7 100644 --- a/src/main/java/umc/codeplay/service/FileService.java +++ b/src/main/java/umc/codeplay/service/FileService.java @@ -8,11 +8,8 @@ import lombok.RequiredArgsConstructor; -import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.presigner.S3Presigner; -import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; -import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest; import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest; import umc.codeplay.apiPayLoad.code.status.ErrorStatus; @@ -48,31 +45,6 @@ private static String sanitizeFileName(String fileName) { return normalizedFileName.replaceAll("\\s+", "_").replaceAll("[^가-힣a-zA-Z0-9.\\-_]", "_"); } - // S3에서 파일을 다운로드할 수 있는 Presigned URL 생성 - public String generateGetPresignedUrl(Long musicId) { - try { - Music music = - musicRepository - .findById(musicId) - .orElseThrow(() -> new GeneralHandler(ErrorStatus.MUSIC_NOT_FOUND)); - - GetObjectRequest getObjectRequest = - GetObjectRequest.builder().bucket(bucketName).key(music.getTitle()).build(); - - GetObjectPresignRequest presignRequest = - GetObjectPresignRequest.builder() - .signatureDuration(Duration.ofMinutes(60)) - .getObjectRequest(getObjectRequest) - .build(); - - PresignedGetObjectRequest presignedRequest = - s3Presigner.presignGetObject(presignRequest); - return presignedRequest.url().toString(); - } catch (Exception e) { - throw new GeneralHandler(ErrorStatus.AWS_SERVICE_UNAVAILABLE); - } - } - // S3에 파일을 업로드할 수 있는 Presigned URL 생성 public String generatePutPresignedUrl(String fileName) { try { @@ -93,6 +65,20 @@ public String generatePutPresignedUrl(String fileName) { } } + // User 레포지토리에 업로드 + public Long uploadProfile(String newFileName, String userEmail) { + Member member = + memberRepository + .findByEmail(userEmail) + .orElseThrow(() -> new GeneralHandler(ErrorStatus.MEMBER_NOT_FOUND)); + + String s3Url = + String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, newFileName); + + member.setProfileUrl(s3Url); + return memberRepository.save(member).getId(); + } + // music 레포지토리에 업로드 public Long uploadMusic(String newFileName, String userEmail) { Member member = @@ -101,13 +87,10 @@ public Long uploadMusic(String newFileName, String userEmail) { .orElseThrow(() -> new GeneralHandler(ErrorStatus.MEMBER_NOT_FOUND)); // 저장하는 url은 유효시간이 없는 public - // TODO: 업로드에만 presigned 사용할지 아님 다운로드시에도 사용할지에 따라 변경해야함. String s3Url = String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, newFileName); Music newMusic = Music.builder().title(newFileName).musicUrl(s3Url).member(member).build(); return musicRepository.save(newMusic).getId(); } - - // TODO: 필요시 직접 업로드 방법 구현 필요 }