diff --git a/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/PostController.java b/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/PostController.java index d1331a4..c5b4cb3 100644 --- a/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/PostController.java +++ b/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/PostController.java @@ -22,6 +22,7 @@ import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -41,7 +42,8 @@ public class PostController { * 이때 로그인되어 있으며 해당 게시글에 좋아요를 눌렀을 경우에는 PostResponseDto 내 likes 필드를 true로 반환합니다. (기본값 false) * * @param authentication 인증정보 - * @return 성공 시 200 OK와 함께 게시글 목록을 반환하며, 실패 시 500 Internal Server Error를 반환합니다. + * @return 성공 시 200 OK와 함께 게시글 목록을 반환합니다. + * 실패 시 500 Internal Server Error를 반환합니다. */ @GetMapping("") public ResponseEntity getAllPosts(Authentication authentication) { @@ -57,7 +59,7 @@ public ResponseEntity getAllPosts(Authentication authentication) { return ResponseEntity.ok(postResponseDtos); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("게시글 조회 중 오류가 발생하였습니다 : " + e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "게시글 조회 중 오류가 발생하였습니다.")); } } @@ -65,7 +67,9 @@ public ResponseEntity getAllPosts(Authentication authentication) { * 특정 게시글 내용 전체를 가져옵니다. * * @param postId 게시글 번호 - * @return 성공 시 200 OK와 함께 게시글 상세 정보를 반환하며, 실패 시 404 Not Found 또는 500 Internal Server Error를 반환합니다. + * @return 성공 시 200 OK와 함께 게시글 상세 정보를 반환합니다. + * 게시글을 찾을 수 없을 때 404 Not Found 를 반환합니다. + * 기타 사유로 실패 시 500 Internal Server Error를 반환합니다. */ @GetMapping("/{postId}") public ResponseEntity getPost(@PathVariable Long postId, Authentication authentication) { @@ -80,10 +84,11 @@ public ResponseEntity getPost(@PathVariable Long postId, Authentication authe PostDetailDto postDetailDto = postService.getPostById(postId, read_member); return ResponseEntity.ok(postDetailDto); } catch (EntityNotFoundException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("해당 게시글이 존재하지 않습니다."); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "POST_NOT_FOUND", "message", "해당 게시글이 존재하지 않습니다.")); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("게시글 조회 중 오류가 발생하였습니다 : " + e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "게시글 조회 중 오류가 발생하였습니다.")); } } @@ -102,29 +107,28 @@ public ResponseEntity changeLikes(@PathVariable Long postId, Authentication a try { if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body("해당 서비스를 이용하기 위해서는 로그인이 필요합니다."); + .body(Map.of("error", "UNAUTHORIZED", "message", "해당 서비스를 이용하기 위해서는 로그인이 필요합니다.")); } postService.isPostExist(postId); // 게시글 존재 여부 확인 String memberEmail = authentication.getName(); Member member = memberService.getMemberByEmail(memberEmail); - if (member == null) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("사용자를 찾을 수 없습니다."); - } - Boolean result = postService.changeLikes(memberEmail, postId); if (result) { - return ResponseEntity.status(HttpStatus.OK).body("좋아요를 눌렀습니다!"); + return ResponseEntity.status(HttpStatus.OK) + .body(Map.of("message","좋아요를 눌렀습니다!")); } else { - return ResponseEntity.status(HttpStatus.OK).body("좋아요를 취소하였습니다!"); + return ResponseEntity.status(HttpStatus.OK) + .body(Map.of("message","좋아요를 취소하였습니다!")); } } catch (EntityNotFoundException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("해당 게시글이 존재하지 않습니다."); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "POST_NOT_FOUND", "message", "해당 게시글이 존재하지 않습니다.")); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("좋아요 상태를 변경하는 중 오류가 발생하였습니다." + e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "좋아요 상태를 변경하는 중 오류가 발생하였습니다.")); } } @@ -137,7 +141,6 @@ public ResponseEntity changeLikes(@PathVariable Long postId, Authentication a * 로그인을 하지 않고 시도 시 401 Unauthorized 에러를 반환합니다. * 서로 다른 2개의 해시태그를 선택하지 않았을 시 400 BAD REQUEST 에러를 반환합니다. * 이미지를 업로드하지 않았거나 4장 이상 업로드 시도 시 400 BAD REQUEST 에러를 반환합니다. - * 사용자를 찾을 수 없을 때는 404 Not Found 에러를 반환합니다. * 기타 이유로 업로드 실패 시 500 Internal Server Error를 반환합니다. */ @PostMapping(value = "", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @@ -148,7 +151,7 @@ public ResponseEntity createPost(Authentication authentication, PostRequestDto postRequestDto = objectMapper.readValue(postRequestDtoJson, PostRequestDto.class); if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body("해당 서비스를 이용하기 위해서는 로그인이 필요합니다."); + .body(Map.of("error", "UNAUTHORIZED", "message", "해당 서비스를 이용하기 위해서는 로그인이 필요합니다.")); } String memberEmail = authentication.getName(); @@ -164,20 +167,24 @@ public ResponseEntity createPost(Authentication authentication, } if (postImages == null || postImages.isEmpty()) { // 이미지 필드 자체가 없는 경우 - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("이미지를 최소 1장 이상 업로드해야 합니다."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "CONDITION_NOT_MET", "message", "이미지를 최소 1장 이상 업로드해야 합니다.")); } if (postImages.size() > 3) { // 이미지가 있으면 최대 3장까지만 허용 - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("이미지는 최대 3장까지 업로드 가능합니다."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "CONDITION_NOT_MET", "message", "이미지는 최대 3장까지 업로드 가능합니다.")); } postService.createPost(postRequestDto, member, postImages); - return ResponseEntity.status(HttpStatus.CREATED).body("게시글을 성공적으로 등록하였습니다."); + return ResponseEntity.status(HttpStatus.CREATED) + .body(Map.of("message", "게시글을 성공적으로 등록하였습니다.")); } catch (RuntimeException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("게시글 등록 중 오류가 발생하였습니다."); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", e.getMessage(), "message", "게시글 등록 중 오류가 발생하였습니다.")); } } @@ -186,7 +193,6 @@ public ResponseEntity createPost(Authentication authentication, * * @param authentication 인증 정보 * @return 성공 시 200 OK와 함께 게시글 목록을 반환합니다. - * 사용자를 찾을 수 없을 때는 404 Not Found 에러를 반환합니다. * 기타 이유로 조회 실패 시 500 Internal Server Error를 반환합니다. */ @GetMapping("/mine") @@ -194,20 +200,17 @@ public ResponseEntity getMyAllPosts(Authentication authentication) { try { if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body("해당 서비스를 이용하기 위해서는 로그인이 필요합니다."); + .body(Map.of("error", "UNAUTHORIZED", "message", "해당 서비스를 이용하기 위해서는 로그인이 필요합니다.")); } String memberEmail = authentication.getName(); Member member = memberService.getMemberByEmail(memberEmail); - if (member == null) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("사용자를 찾을 수 없습니다."); - } List postResponseDto = postService.getMyAllPosts(member); return ResponseEntity.ok(postResponseDto); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("게시글 조회 중 오류가 발생하였습니다. " + e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "게시글 조회 중 오류가 발생하였습니다.")); } } @@ -218,7 +221,7 @@ public ResponseEntity getMyAllPosts(Authentication authentication) { * @param authentication 인증정보 * @return 삭제 성공 시 204 No content 를 반환합니다. * 로그인을 하지 않고 시도 시 401 Unauthorized 에러를 반환합니다. - * 사용자나 게시글을 찾을 수 없을 때는 404 Not Found 에러를 반환합니다. + * 게시글을 찾을 수 없을 때는 404 Not Found 에러를 반환합니다. * 삭제하려는 글이 본인이 작성한 글이 아닐 경우 403 Forbidden 에러를 반환힙니다. * 기타 이유로 게시글 삭제 실패 시 500 Internal Server Error를 반환합니다. */ @@ -227,7 +230,7 @@ public ResponseEntity deletePost(@PathVariable Long postId, Authentication au try { if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body("해당 서비스를 이용하기 위해서는 로그인이 필요합니다."); + .body(Map.of("error", "UNAUTHORIZED", "message", "해당 서비스를 이용하기 위해서는 로그인이 필요합니다.")); } postService.isPostExist(postId); // 게시글 존재 여부 확인 @@ -236,17 +239,33 @@ public ResponseEntity deletePost(@PathVariable Long postId, Authentication au Member member = memberService.getMemberByEmail(memberEmail); postService.deletePost(member, postId); - return ResponseEntity.status(HttpStatus.NO_CONTENT).body("게시글을 성공적으로 삭제하였습니다."); + return ResponseEntity.status(HttpStatus.NO_CONTENT) + .body(Map.of("message", "게시글을 성공적으로 삭제하였습니다.")); } catch (EntityNotFoundException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("해당 게시글이 존재하지 않습니다."); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "POST_NOT_FOUND", "message", "해당 게시글이 존재하지 않습니다.")); } catch (AccessDeniedException e) { return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage()); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("게시글 삭제 중 오류가 발생하였습니다."+ e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "게시글 삭제 중 오류가 발생하였습니다.")); } } + /** + * 본인이 작성한 글을 수정합니다. + * + * @param postId 게시글 정보 + * @param authentication 인증 정보 + * @param postUpdateDtoJson 게시글 수정 정보 (제목, 본문, 해시태그, 삭제할 이미지 url) + * @param postImages 추가할 이미지 파일 + * @return 게시글 수정 성공 시 200 ok를 반환합니다. + * 로그인을 하지 않고 시도 시 401 Unauthorized 에러를 반환합니다. + * 게시글을 찾을 수 없을 때는 404 Not Found 에러를 반환합니다. + * 삭제하려는 글이 본인이 작성한 글이 아닐 경우 403 Forbidden 에러를 반환힙니다. + * 게시글 수정 결과가 게시글의 조건을 충족하지 못할 경우 400 BAD REQUEST 에러를 반환합니다. + * @throws JsonProcessingException + */ @PatchMapping(value = "/{postId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity updatePost(@PathVariable Long postId, Authentication authentication, @@ -257,7 +276,7 @@ public ResponseEntity updatePost(@PathVariable Long postId, if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body("해당 서비스를 이용하기 위해서는 로그인이 필요합니다."); + .body(Map.of("error", "UNAUTHORIZED", "message", "해당 서비스를 이용하기 위해서는 로그인이 필요합니다.")); } String memberEmail = authentication.getName(); @@ -274,20 +293,26 @@ public ResponseEntity updatePost(@PathVariable Long postId, if (postImage != null && !postImage.isEmpty()) validImageCnt++; } if (nextImageCnt + validImageCnt > 3) // 최종 이미지 개수 - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("이미지는 최대 3장까지 업로드 가능합니다."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "CONDITION_NOT_MET", "message", "이미지는 최대 3장까지 업로드 가능합니다.")); } postUpdateDto.validate(nowImageCnt, validImageCnt); // 제목, 본문, 해시태그, 삭제할 이미지 검증 postService.updatePost(postId, postUpdateDto, member, postImages); - return ResponseEntity.status(HttpStatus.OK).body("게시글을 성공적으로 수정했습니다."); + return ResponseEntity.status(HttpStatus.OK) + .body(Map.of("message", "게시글을 성공적으로 수정했습니다.")); } catch (EntityNotFoundException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("해당 게시글이 존재하지 않습니다."); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "POST_NOT_FOUND", "message", "해당 게시글이 존재하지 않습니다.")); } catch (AccessDeniedException e) { - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage()); + return ResponseEntity.status(HttpStatus.FORBIDDEN) + .body(Map.of("error", "FORBIDDEN", "message", e.getMessage())); } catch (RuntimeException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "CONDITION_NOT_MET", "message", e.getMessage())); } catch (Exception e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("게시글 수정 중 오류가 발생하였습니다." + e.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", e.getMessage(), "message", "게시글 수정 중 오류가 발생하였습니다.")); } } } \ No newline at end of file diff --git a/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/SearhController.java b/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/SearhController.java index e1f4078..769410f 100644 --- a/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/SearhController.java +++ b/src/main/java/com/solucitation/midpoint_backend/domain/community_board/api/SearhController.java @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.Map; import java.util.Optional; @Slf4j @@ -47,10 +48,11 @@ public ResponseEntity searchByPurpose(Authentication authentication, @Request List postResponseDto = postService.getPostByPurpose(member, purposes); return ResponseEntity.ok(postResponseDto); } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "CONDITION_NOT_MET", "message", e.getMessage())); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("게시글 검색 중 오류가 발생하였습니다. " + e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "게시글 검색 중 오류가 발생하였습니다.")); } } @@ -77,10 +79,11 @@ public ResponseEntity searchByQuery(Authentication authentication, @RequestPa List postResponseDto = postService.getPostByQuery(member, query); return ResponseEntity.ok(postResponseDto); } catch (IllegalArgumentException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "CONDITION_NOT_MET", "message", e.getMessage())); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("게시글 검색 중 오류가 발생하였습니다. " + e.getMessage()); + .body(Map.of("error", e.getMessage(), "message", "게시글 검색 중 오류가 발생하였습니다.")); } } } \ No newline at end of file diff --git a/src/main/java/com/solucitation/midpoint_backend/domain/history2/api/SearchHistoryControllerV2.java b/src/main/java/com/solucitation/midpoint_backend/domain/history2/api/SearchHistoryControllerV2.java index 75f551c..ce54cc1 100644 --- a/src/main/java/com/solucitation/midpoint_backend/domain/history2/api/SearchHistoryControllerV2.java +++ b/src/main/java/com/solucitation/midpoint_backend/domain/history2/api/SearchHistoryControllerV2.java @@ -49,18 +49,18 @@ public ResponseEntity saveHistory(Authentication authentication, String neighborhood = request.getNeighborhood(); List searchHistoryRequestDtos = request.getHistoryDto(); - // neighborhood 검증 - if (neighborhood == null || neighborhood.trim().isEmpty()) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(Map.of("error", "EMPTY_FIELD", "message", "동 정보가 누락되었습니다.")); - } - // 인증 검증 if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) .body(Map.of("error", "UNAUTHORIZED", "message", "해당 서비스를 이용하기 위해서는 로그인이 필요합니다.")); } + // neighborhood 검증 + if (neighborhood == null || neighborhood.trim().isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", "EMPTY_FIELD", "message", "동 정보가 누락되었습니다.")); + } + String memberEmail = authentication.getName(); Member member = memberService.getMemberByEmail(memberEmail); @@ -82,9 +82,6 @@ public ResponseEntity saveHistory(Authentication authentication, } catch (IllegalArgumentException e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); - } catch (RuntimeException e) { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(Map.of("error", "NOT_FOUND", "message", e.getMessage())); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(Map.of("error", e.getMessage(), "message", "장소 저장 중 오류가 발생하였습니다."));