불필요하게 save 메서드를 호출하던 부분들을 수정했습니다. (postserviceimpl, commentserviceimpl)
` public Post updatePost(Post post) {
Post existingPost = getPost(post.getId());
Post updatedPost = existingPost.toBuilder()
.title(post.getTitle())
.content(post.getContent())
.images(post.getImages())
.build();
return updatedPost;
}`
익명으로 글 작성 시 nickname과 profileImage 다음과 같이 매핑되도록 했습니다.
@AfterMapping default void setUserProfile(@MappingTarget PostResponseDto.PostListResponseDto.PostListResponseDtoBuilder dto, Post post, @Context UserProfileRepository userProfileRepository) { if (post.isAnonymous()) { dto.nickname("익명"); dto.profileImage("http://example.com/default-profile.png"); } else if (post.getUser() != null) { Optional<UserProfile> userProfileOptional = userProfileRepository.findByUserId(post.getUser().getId()); userProfileOptional.ifPresent(userProfile -> { dto.nickname(userProfile.getNickname()); dto.profileImage(userProfile.getProfileImage()); }); } } 그런데 익명시 프로필 이미지를 url로 받아오는게 나을지, 아니면 db에 저장 후 불러오는 방법이 나을지는 세빈님과 논의 중에 있습니다. (결정 후 수정하겠습니다)
익명으로 댓글 작성 시 익명 1, 익명 2와 같이 숫자가 증가해야 하기 때문에 commentserviceimpl에 다음과 같은 메서드 구현했습니다.
@Override public String generateAnonymousNickname(Long postId, String userId) { List<Comment> userComments = commentRepository.findByPostIdAndUserIdAndAnonymous(postId, userId, true); if (!userComments.isEmpty()) { return userComments.get(0).getNickname(); } else { long anonymousCount = commentRepository.countByPostIdAndAnonymous(postId, true); return "익명 " + (anonymousCount + 1); } }
🛠️ 개발 오류 사항
알림창을 구현하기 위해 SSE 방식으로 구현하고자 했으나 엔드포인트에 접근 시 무한로딩 현상이 발생하고 있습니다.
관련 코드들은 다음과 같습니다.
1. notification.java
`@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Table(name = "notification")
public class Notification {
@jakarta.persistence.Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
💻 구현 내용
postserviceimpl
,commentserviceimpl
내 레포지토리 네이밍 변경getPost
,getComment
메서드 사용하여 중복되는 코드 수정commentserviceimpl에서 ` public void deleteComment(Long commentId) { Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new BusinessException(ErrorCode.NOT_FOUND_COMMENT));
}
@Transactional public void deleteChildrenComment(Long commentId) { commentRepository.deleteByParentId(commentId); }` 로 부모댓글과 자식댓글 삭제를 따로따로 구현하도록 변경했습니다.
다은님께서 작성해주신 paging 기반으로 responsedto를 변경했습니다. ` public class PostResponseDto {
private List postList;
private PagingResponse paging;
@Getter @Builder @AllArgsConstructor @NoArgsConstructor public static class PostListResponseDto { private Long id; private String userId; private String title; private String content; private boolean anonymous; private List images;
private long likeCount;
private long commentCount;
private long scrapCount;
private long viewCount;
private CategoryName category;
private List comments; // 수정된 부분
private String nickname;
private String profileImage;
} }
로 변경하여 응답값 다음과 같습니다.
{ "postList": [ { "id": 1, "userId": "fe57595b62334291900b48ac0f4444c0", "title": "10대 테스트 게시글 1 수정 제목입니다.", "content": "10대 테스트 게시글 1 수정 내용입니다.", "anonymous": false, "images": [ "http://edit", "http://edit2" ], "likeCount": 0, "commentCount": 0, "scrapCount": 0, "viewCount": 0, "category": "TEENS", "comments": [], "nickname": "이헨", "profileImage": "http://", "createdAt": 1721706872, "lastModifiedAt": 1721707233 }, { "id": 2, "userId": "fe57595b62334291900b48ac0f4444c0", "title": "10대 테스트 게시글 2", "content": "10대 테스트 게시글 2입니다.", "anonymous": true, "images": [ "http://ex", "http://ex2" ], "likeCount": 0, "commentCount": 0, "scrapCount": 0, "viewCount": 0, "category": "TEENS", "comments": [], "nickname": "익명", "profileImage": "http://example.com/default-profile.png", "createdAt": 1721706887, "lastModifiedAt": 1721706887 } ], "paging": { "page": 0, "size": 20, "totalPages": 1, "numberOfElements": 2, "totalElements": 2, "isFirst": true, "isLast": true, "isEmpty": false } }`불필요하게 save 메서드를 호출하던 부분들을 수정했습니다. (postserviceimpl, commentserviceimpl) ` public Post updatePost(Post post) { Post existingPost = getPost(post.getId());
}`
익명으로 글 작성 시 nickname과 profileImage 다음과 같이 매핑되도록 했습니다.
@AfterMapping default void setUserProfile(@MappingTarget PostResponseDto.PostListResponseDto.PostListResponseDtoBuilder dto, Post post, @Context UserProfileRepository userProfileRepository) { if (post.isAnonymous()) { dto.nickname("익명"); dto.profileImage("http://example.com/default-profile.png"); } else if (post.getUser() != null) { Optional<UserProfile> userProfileOptional = userProfileRepository.findByUserId(post.getUser().getId()); userProfileOptional.ifPresent(userProfile -> { dto.nickname(userProfile.getNickname()); dto.profileImage(userProfile.getProfileImage()); }); } }
그런데 익명시 프로필 이미지를 url로 받아오는게 나을지, 아니면 db에 저장 후 불러오는 방법이 나을지는 세빈님과 논의 중에 있습니다. (결정 후 수정하겠습니다)익명으로 댓글 작성 시 익명 1, 익명 2와 같이 숫자가 증가해야 하기 때문에 commentserviceimpl에 다음과 같은 메서드 구현했습니다.
@Override public String generateAnonymousNickname(Long postId, String userId) { List<Comment> userComments = commentRepository.findByPostIdAndUserIdAndAnonymous(postId, userId, true); if (!userComments.isEmpty()) { return userComments.get(0).getNickname(); } else { long anonymousCount = commentRepository.countByPostIdAndAnonymous(postId, true); return "익명 " + (anonymousCount + 1); } }
🛠️ 개발 오류 사항
1. notification.java `@Getter @NoArgsConstructor @AllArgsConstructor @Builder(toBuilder = true) @Table(name = "notification") public class Notification { @jakarta.persistence.Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
} `
2. NotificationServiceImpl
3. notificationcontroller `@RestController @RequestMapping("/api/v1/notifications") @RequiredArgsConstructor @CrossOrigin(origins = {"http://localhost:3000", "http://localhost:8080"}) public class NotificationController { private final NotificationService notificationService; private final SseEmitters sseEmitters;
} `
4. SseEmitters `@Component public class SseEmitters { private final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();
} `
이와 관련해서 CORS 에러가 발생했어서, webconfig와 securityconfig에 다음과 같은 내용 추가하였습니다.
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("http://localhost:3000", "http://localhost:8080") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }
@RequiredArgsConstructor @EnableWebSecurity @Configuration public class SecurityConfig { @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOriginPatterns(Arrays.asList("http://localhost:3000", "http://localhost:8080")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
🗣️ For 리뷰어
close #42