From 5b37e931500635ac9878221e187c07c654c3fb0a Mon Sep 17 00:00:00 2001 From: Kwonnamhyung Date: Tue, 30 Jul 2024 22:09:15 +0900 Subject: [PATCH 1/6] =?UTF-8?q?commonService=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/application/CommonService.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/com/example/yeogiserver/common/application/CommonService.java diff --git a/src/main/java/com/example/yeogiserver/common/application/CommonService.java b/src/main/java/com/example/yeogiserver/common/application/CommonService.java new file mode 100644 index 0000000..33d87c0 --- /dev/null +++ b/src/main/java/com/example/yeogiserver/common/application/CommonService.java @@ -0,0 +1,35 @@ +package com.example.yeogiserver.common.application; + +import com.example.yeogiserver.common.exception.CustomException; +import com.example.yeogiserver.common.exception.ErrorCode; +import com.example.yeogiserver.member.domain.Member; +import com.example.yeogiserver.member.domain.MemberRepository; +import com.example.yeogiserver.member.repository.DefaultMemberRepository; +import com.example.yeogiserver.security.domain.CustomUserDetails; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Optional; + +@Component +@RequiredArgsConstructor +public class CommonService { + + private final DefaultMemberRepository memberRepository; + + public String getTime() { + + ZonedDateTime dateTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); + + return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + + public String getName(CustomUserDetails customUserDetails) { + Member member = memberRepository.findById(customUserDetails.getId()).orElseThrow(() -> new CustomException(ErrorCode.MEMBER_NOT_FOUND)); + return member.getNickname(); + } +} From c5ea3bf3219166ed8499de95b735b9adfd408eb6 Mon Sep 17 00:00:00 2001 From: Kwonnamhyung Date: Tue, 30 Jul 2024 22:09:37 +0900 Subject: [PATCH 2/6] =?UTF-8?q?POST=20=EB=A1=9C=EA=B7=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/presentation/PostController.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/yeogiserver/post/presentation/PostController.java b/src/main/java/com/example/yeogiserver/post/presentation/PostController.java index ab1aa83..ea2b746 100644 --- a/src/main/java/com/example/yeogiserver/post/presentation/PostController.java +++ b/src/main/java/com/example/yeogiserver/post/presentation/PostController.java @@ -1,5 +1,6 @@ package com.example.yeogiserver.post.presentation; +import com.example.yeogiserver.common.application.CommonService; import com.example.yeogiserver.post.application.PostService; import com.example.yeogiserver.post.application.dto.request.PostRequestDto; import com.example.yeogiserver.post.application.dto.request.PostUpdateRequest; @@ -8,6 +9,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; @@ -24,9 +26,11 @@ @RequiredArgsConstructor @SecurityRequirement(name = "Bearer Authentication") @Tag(name = "게시글 쓰기(C,U,D) 컨트롤러") +@Slf4j public class PostController { private final PostService postService; + private final CommonService commonService; @PostMapping("/posts") @Operation(description = "게시글을 생성한다.") @@ -39,37 +43,44 @@ public ResponseEntity createPost(@RequestBody PostRequestDto postRequestDt .buildAndExpand(postId) .toUri(); + log.info("[CREATE POST] TIME = {} , ID = {} , USER = {}" , commonService.getTime() , postId , commonService.getName(userDetails)); + // 201 Created 응답과 Location 헤더를 반환 return ResponseEntity.created(location).build(); } @PostMapping("/posts/{postId}/views") @Operation(description = "postId 에 해당하는 게시글의 조회수를 추가 한다.") - public void addViewCount(@PathVariable Long postId){ + public void addViewCount(@PathVariable Long postId , @AuthenticationPrincipal CustomUserDetails userDetails){ postService.addViewCount(postId); + log.info("[ADD VIEW COUNT] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @PutMapping("/posts/{postId}") @Operation(description = "postId 에 해당하는 게시글을 수정한다.") public void updatePost(@PathVariable Long postId, @RequestBody PostUpdateRequest postRequestDto, @AuthenticationPrincipal CustomUserDetails userDetails) { postService.updatePost(postId, postRequestDto, userDetails.getId()); + log.info("[UPDATE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @DeleteMapping("/posts/{postId}") @Operation(description = "postId 에 해당하는 게시글을 삭제한다.") - public void deletePost(@PathVariable Long postId) { + public void deletePost(@PathVariable Long postId , @AuthenticationPrincipal CustomUserDetails userDetails) { postService.delete(postId); + log.info("[DELETE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @PostMapping("/posts/{postId}/likes") @Operation(description = "postId 에 해당하는 게시글의 좋아요를 생성한다.") public void likePost(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long postId) { postService.likePost(userDetails.getId(), postId); + log.info("[LIKE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @DeleteMapping("/posts/{postId}/likes") @Operation(description = "postId 에 해당하는 게시글의 좋아요를 삭제한다.") public void unlikePost(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long postId) { postService.dislikePost(userDetails.getId(), postId); + log.info("[DISLIKE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } } From 8216f0d2ae7bb15e94311e0a55da185db8a09019 Mon Sep 17 00:00:00 2001 From: Kwonnamhyung Date: Wed, 31 Jul 2024 21:41:52 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=ED=8F=AC=EC=8A=A4=ED=8A=B8=20Error=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/ErrorCode.java | 7 ++++++- .../post/application/PostService.java | 21 +++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/yeogiserver/common/exception/ErrorCode.java b/src/main/java/com/example/yeogiserver/common/exception/ErrorCode.java index 05b28c3..4c251a8 100644 --- a/src/main/java/com/example/yeogiserver/common/exception/ErrorCode.java +++ b/src/main/java/com/example/yeogiserver/common/exception/ErrorCode.java @@ -23,8 +23,13 @@ public enum ErrorCode { HEADER_REFRESH_TOKEN_NOT_EXISTS(404 , "헤더에 Refresh 토큰이 존재하지 않습니다."), //OAuth - ILLEGAL_REGISTRATION_ID(400 , "올바르지 않은 registrationId 입니다."); + ILLEGAL_REGISTRATION_ID(400 , "올바르지 않은 registrationId 입니다."), + //POST + POST_NOT_FOUND(500 , "포스트를 찾을 수 없습니다."), + NOT_MY_POST(501 , "사용자가 작성한 포스트가 아닙니다."), + MEMBER_ALREADY_LIKE_POST(502 , "사용자가 이미 좋아요를 누른 포스트입니다."), + MEMBER_ALREADY_DISLIKE_POST(503 , "사용자가 이미 싫어요를 누른 포스트입니다."); private int status; diff --git a/src/main/java/com/example/yeogiserver/post/application/PostService.java b/src/main/java/com/example/yeogiserver/post/application/PostService.java index d68578f..99d2abf 100644 --- a/src/main/java/com/example/yeogiserver/post/application/PostService.java +++ b/src/main/java/com/example/yeogiserver/post/application/PostService.java @@ -1,5 +1,7 @@ package com.example.yeogiserver.post.application; +import com.example.yeogiserver.common.exception.CustomException; +import com.example.yeogiserver.common.exception.ErrorCode; import com.example.yeogiserver.event.recommand.RecommandEvent; import com.example.yeogiserver.member.application.MemberQueryService; import com.example.yeogiserver.member.domain.Member; @@ -34,11 +36,12 @@ public class PostService { private final ApplicationEventPublisher applicationEventPublisher; private Post getPost(Long id) { - return postRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Post not found")); + return postRepository.findById(id).orElseThrow(() -> new CustomException(ErrorCode.POST_NOT_FOUND)); } public void addViewCount(Long postId){ - postRepository.addViewCount(postId); + Post post = getPost(postId); + postRepository.addViewCount(post.getId()); } public Long createPost(Long memberId, PostRequestDto postRequestDto) { @@ -68,7 +71,7 @@ public void updatePost(Long id, PostUpdateRequest postUpdateRequest, Long member Post post = getPost(id); if (!Objects.equals(post.getAuthor().getId(), memberId)) { - throw new IllegalArgumentException("Not my Post"); + throw new CustomException(ErrorCode.NOT_MY_POST); } post.updateFields(postUpdateRequest.continent(), postUpdateRequest.country(), postUpdateRequest.tripStartDate(), postUpdateRequest.tripEndDate(), postUpdateRequest.title(), postUpdateRequest.content(), postUpdateRequest.address()); @@ -105,14 +108,20 @@ private void updateProjectTheme(List themeList, Post post) { post.replaceThemeList(postThemeList); } - public void delete(Long id) { + public void delete(Long id , Long memberId) { + Post post = getPost(id); + + if (!Objects.equals(post.getAuthor().getId(), memberId)) { + throw new CustomException(ErrorCode.NOT_MY_POST); + } + postRepository.deleteById(id); } public void likePost(Long memberId, Long postId){ boolean likeExist = postRepository.isLikeExist(postId, memberId); if (likeExist){ - throw new IllegalArgumentException("Member already like this post"); + throw new CustomException(ErrorCode.MEMBER_ALREADY_LIKE_POST); } Post post = getPost(postId); @@ -123,7 +132,7 @@ public void likePost(Long memberId, Long postId){ public void dislikePost(Long memberId, Long postId){ PostLike postLike = postRepository.findPostLikeByPostIdAndMemberId(postId, memberId).orElseThrow( - () -> new IllegalArgumentException("Member has not like this post") + () -> new CustomException(ErrorCode.MEMBER_ALREADY_DISLIKE_POST) ); Post post = getPost(postId); From 956e7a2bea2551316e84061a4b17a2c9a1d0c33d Mon Sep 17 00:00:00 2001 From: Kwonnamhyung Date: Wed, 31 Jul 2024 21:42:16 +0900 Subject: [PATCH 4/6] =?UTF-8?q?=ED=8F=AC=EC=8A=A4=ED=8A=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=8B=9C=20,=20=EC=9E=91=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/yeogiserver/post/presentation/PostController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/yeogiserver/post/presentation/PostController.java b/src/main/java/com/example/yeogiserver/post/presentation/PostController.java index ea2b746..c5671dc 100644 --- a/src/main/java/com/example/yeogiserver/post/presentation/PostController.java +++ b/src/main/java/com/example/yeogiserver/post/presentation/PostController.java @@ -66,7 +66,7 @@ public void updatePost(@PathVariable Long postId, @RequestBody PostUpdateRequest @DeleteMapping("/posts/{postId}") @Operation(description = "postId 에 해당하는 게시글을 삭제한다.") public void deletePost(@PathVariable Long postId , @AuthenticationPrincipal CustomUserDetails userDetails) { - postService.delete(postId); + postService.delete(postId , userDetails.getId()); log.info("[DELETE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } From 08e23136e94aad0a5b3ab1f69e25bfbddbe106d4 Mon Sep 17 00:00:00 2001 From: Kwonnamhyung Date: Wed, 31 Jul 2024 21:42:34 +0900 Subject: [PATCH 5/6] =?UTF-8?q?CustomException=20=EB=A1=9C=EA=B9=85=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/advice/GlobalControllerAdvice.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/example/yeogiserver/base/presentation/advice/GlobalControllerAdvice.java b/src/main/java/com/example/yeogiserver/base/presentation/advice/GlobalControllerAdvice.java index ed4f594..543b616 100644 --- a/src/main/java/com/example/yeogiserver/base/presentation/advice/GlobalControllerAdvice.java +++ b/src/main/java/com/example/yeogiserver/base/presentation/advice/GlobalControllerAdvice.java @@ -1,18 +1,29 @@ package com.example.yeogiserver.base.presentation.advice; import com.example.yeogiserver.common.exception.CustomException; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + @RestControllerAdvice +@Slf4j public class GlobalControllerAdvice { @ExceptionHandler(RuntimeException.class) public ResponseEntity handleException(RuntimeException e) { if(e instanceof CustomException) { + + ZonedDateTime dateTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); + + log.warn("[ERROR] TIME = {} , MESSAGE = {}" , dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) , ((CustomException) e).getErrorCode().getMessage()); + return ResponseEntity .status(((CustomException) e).getErrorCode().getStatus()) .body(new ErrorResponse(((CustomException) e).getErrorCode().getMessage() , HttpStatus.valueOf(((CustomException) e).getErrorCode().getStatus()))); From 8ebb8b376539b0af083dcae7c748263ec8e2120a Mon Sep 17 00:00:00 2001 From: Kwonnamhyung Date: Tue, 6 Aug 2024 21:28:28 +0900 Subject: [PATCH 6/6] =?UTF-8?q?logging=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yeogiserver/post/presentation/PostController.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/com/example/yeogiserver/post/presentation/PostController.java b/src/main/java/com/example/yeogiserver/post/presentation/PostController.java index c5671dc..6f2319d 100644 --- a/src/main/java/com/example/yeogiserver/post/presentation/PostController.java +++ b/src/main/java/com/example/yeogiserver/post/presentation/PostController.java @@ -43,8 +43,6 @@ public ResponseEntity createPost(@RequestBody PostRequestDto postRequestDt .buildAndExpand(postId) .toUri(); - log.info("[CREATE POST] TIME = {} , ID = {} , USER = {}" , commonService.getTime() , postId , commonService.getName(userDetails)); - // 201 Created 응답과 Location 헤더를 반환 return ResponseEntity.created(location).build(); } @@ -53,34 +51,29 @@ public ResponseEntity createPost(@RequestBody PostRequestDto postRequestDt @Operation(description = "postId 에 해당하는 게시글의 조회수를 추가 한다.") public void addViewCount(@PathVariable Long postId , @AuthenticationPrincipal CustomUserDetails userDetails){ postService.addViewCount(postId); - log.info("[ADD VIEW COUNT] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @PutMapping("/posts/{postId}") @Operation(description = "postId 에 해당하는 게시글을 수정한다.") public void updatePost(@PathVariable Long postId, @RequestBody PostUpdateRequest postRequestDto, @AuthenticationPrincipal CustomUserDetails userDetails) { postService.updatePost(postId, postRequestDto, userDetails.getId()); - log.info("[UPDATE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @DeleteMapping("/posts/{postId}") @Operation(description = "postId 에 해당하는 게시글을 삭제한다.") public void deletePost(@PathVariable Long postId , @AuthenticationPrincipal CustomUserDetails userDetails) { postService.delete(postId , userDetails.getId()); - log.info("[DELETE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @PostMapping("/posts/{postId}/likes") @Operation(description = "postId 에 해당하는 게시글의 좋아요를 생성한다.") public void likePost(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long postId) { postService.likePost(userDetails.getId(), postId); - log.info("[LIKE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } @DeleteMapping("/posts/{postId}/likes") @Operation(description = "postId 에 해당하는 게시글의 좋아요를 삭제한다.") public void unlikePost(@AuthenticationPrincipal CustomUserDetails userDetails, @PathVariable Long postId) { postService.dislikePost(userDetails.getId(), postId); - log.info("[DISLIKE POST] TIME = {} , ID = {} , USER = {} " , commonService.getTime() , postId , commonService.getName(userDetails)); } }