From 5ff250e558dbf3f847c46896847bfa8ee44b0d95 Mon Sep 17 00:00:00 2001 From: SeungWoo Ryu Date: Mon, 15 Dec 2025 21:07:46 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix=20:=20swagger=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=82=B4=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=8F=99=EC=9E=91=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - swagger 페이지에서 서버(배포 서버와 로컬 서버)를 선택할 수 있도록 함 --- .../swagger/config/SwaggerConfig.java | 4 ++++ .../usermanagement/UserController.java | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java b/src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java index 6dde2f07..f607d163 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/swagger/config/SwaggerConfig.java @@ -16,6 +16,10 @@ @Server( url = "https://api.ezcode.my", // ← 슬래시 없이 호스트만! description = "Production server" + ), + @Server( + url = "http://localhost:8080", + description = "Local Server" ) }, info = @Info(title = "API 문서", version = "v1"), diff --git a/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java b/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java index 27f2c0f4..f4250bd6 100644 --- a/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java +++ b/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java @@ -1,10 +1,8 @@ package org.ezcode.codetest.presentation.usermanagement; -import org.ezcode.codetest.application.submission.dto.response.language.LanguageResponse; import org.ezcode.codetest.application.usermanagement.user.dto.request.ModifyUserInfoRequest; import org.ezcode.codetest.application.usermanagement.user.dto.request.ChangeUserPasswordRequest; import org.ezcode.codetest.application.usermanagement.user.dto.response.ChangeUserPasswordResponse; -import org.ezcode.codetest.application.usermanagement.user.dto.response.GrantAdminRoleResponse; import org.ezcode.codetest.application.usermanagement.user.dto.response.UserDailySolvedHistoryResponse; import org.ezcode.codetest.application.usermanagement.user.dto.response.UserInfoResponse; import org.ezcode.codetest.application.usermanagement.user.dto.response.UserProfileImageResponse; @@ -26,6 +24,9 @@ import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Encoding; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -46,7 +47,17 @@ public ResponseEntity getUserInfo(@AuthenticationPrincipal Aut return ResponseEntity.status(HttpStatus.OK).body(userService.getUserInfo(authUser)); } - @Operation(summary = "내 정보 수정", description = "닉네임, 블로그, 깃허브, 소개 등 개인 정보를 추가하거나 수정합니다.") + @Operation( + summary = "내 정보 수정", + description = "닉네임, 블로그, 깃허브, 소개 등 개인 정보를 추가하거나 수정합니다.", + // ▼ 이 부분이 핵심입니다. Swagger에게 'request' 파트의 Content-Type을 강제합니다. + requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody( + content = @Content( + mediaType = MediaType.MULTIPART_FORM_DATA_VALUE, + encoding = @Encoding(name = "request", contentType = MediaType.APPLICATION_JSON_VALUE) + ) + ) + ) @PutMapping(value = "/users", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity modifyUserInfo( @AuthenticationPrincipal AuthUser authUser, From a04cd12b54df9a16bb982dd1f2989318d774e912 Mon Sep 17 00:00:00 2001 From: SeungWoo Ryu Date: Mon, 15 Dec 2025 22:13:39 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix=20:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20?= =?UTF-8?q?=EB=8D=94=20=EC=9D=B4=EC=83=81=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EA=B8=B0=EC=A1=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EA=B0=80=20s3=20=EB=B2=84=ED=82=B7=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=82=AD=EC=A0=9C=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 삭제할 버킷의 이미지의 변수가 새로운 이미지 URL을 참조하고 있었음 - 인코딩 문제 해결 --- .../usermanagement/user/service/UserService.java | 6 +++--- .../org/ezcode/codetest/infrastructure/s3/S3Uploader.java | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java index 2cda108d..d38a5b29 100644 --- a/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java @@ -106,10 +106,10 @@ public UserInfoResponse modifyUserInfo(AuthUser authUser, ModifyUserInfoRequest String oldImageUrl = user.getProfileImageUrl(); user.modifyProfileImage(profileImageUrl); - if (oldImageUrl!=null) { - s3Uploader.delete(user.getProfileImageUrl(), "profile"); - } + if (oldImageUrl != null) { + s3Uploader.delete(oldImageUrl, "profile"); + } } return UserInfoResponse.builder() diff --git a/src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java b/src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java index 8198352c..c5f05088 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/s3/S3Uploader.java @@ -1,6 +1,8 @@ package org.ezcode.codetest.infrastructure.s3; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.UUID; import org.ezcode.codetest.infrastructure.s3.exception.S3Exception; @@ -78,7 +80,10 @@ public void delete(String fileUrl, String dirName) { if (dirName.equalsIgnoreCase("profile")) { fileName = extractKeyFromProfileUrl(fileUrl); } - amazonS3.deleteObject(bucket, fileName); // S3 내 이미지 객체 제거. + + String decodedFileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8); + amazonS3.deleteObject(bucket, decodedFileName); // S3 내 이미지 객체 제거. + log.info("S3에서 이미지 삭제 완료: {}", fileName); } catch (Exception e) { log.error("S3 이미지 삭제 실패: {}", fileUrl, e); From 894dabe71d86bb89095f435ab0774753e6b8a72f Mon Sep 17 00:00:00 2001 From: SeungWoo Ryu Date: Mon, 15 Dec 2025 22:48:28 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix=20:=20oldImageUrl=EC=9D=B4=20=EB=B9=88?= =?UTF-8?q?=20=EB=AC=B8=EC=9E=90=EC=97=B4("")=EC=9D=BC=20=EB=95=8C?= =?UTF-8?q?=EC=97=90=EB=8F=84=20=EC=A0=95=EC=83=81=EC=A0=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/usermanagement/user/service/UserService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java index d38a5b29..32ff7efa 100644 --- a/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/service/UserService.java @@ -35,6 +35,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import lombok.RequiredArgsConstructor; @@ -107,7 +108,7 @@ public UserInfoResponse modifyUserInfo(AuthUser authUser, ModifyUserInfoRequest user.modifyProfileImage(profileImageUrl); - if (oldImageUrl != null) { + if (StringUtils.hasText(oldImageUrl)) { s3Uploader.delete(oldImageUrl, "profile"); } }