커뮤니티 프로젝트

댓글 삭제 개발

쭈녁 2022. 12. 7. 18:19

 

Controller

@Transactional
@GetMapping("/comment/delete/{commentId}")
public String deleteComment(@Valid @ModelAttribute Comment comment, @AuthenticationPrincipal PrincipalDetail principalDetail, @PathVariable Long commentId, RedirectAttributes redirectAttributes) {
    Comment findComment = commentService.findById(commentId).get();
    Long postId = findComment.getPost().getId();
    log.info("댓글 삭제요청={}", findComment);

    if (findComment.getMember() == null || !findComment.getMember().equals(principalDetail.getMember())) {
        redirectAttributes.addAttribute("commentDeleteFail", true);
        redirectAttributes.addAttribute("commentId", findComment.getId());
        return "redirect:/post/" + postId;
    }
    commentService.delete(commentId);
    redirectAttributes.addAttribute("commentDelete", true);
    redirectAttributes.addAttribute("commentId", findComment.getId());
    return "redirect:/post/" + postId;
}

댓글 삭제에 대한 요청이 오면 GetMapping을 적용하였다. 조건에 맞게 URL을 던져주었는데 아래와 같이 작성해 보았다.

클라이언트 단에서 commentId를 받아 파라미터로 활용하여 해당 댓글을 리포지터리에서 찾아온다.

게시물의 ID는 해당 댓글은 1개의 게시물과 연관된 데이터이기 때문에 해당 댓글이 가지고 있는 Post객체에서 가져올수 있다.

 

찾아온 댓글의 Member와 로그인된 사용자의 Member객체를 비교하여 다르면 삭제를 진행하지 않고 상태를 댓글 삭제 실패로 변경하여 리다이랙션을 통해 해당페이지에 그대로 머물게 하고 클라이언트에게 댓글 삭제 권한이 없음을 클라이언트 단에서 안내하였다.

 

이 조건에 걸리지 않으면 댓글 작성자와 로그인한 사용자의 정보가 같음으로 댓글을 삭제하고 상태를 댓글 삭제 완료로 변경한 뒤 댓글 삭제가 완료 되었음을 클라이언트 단에서 표기하였다.

 

Service

public void delete(Long commentId) {
    repository.delete(
            repository.findById(commentId).orElseThrow(()-> new EntityNotFoundException("댓글이 존재하지 않습니다."))
    );
}

서비스단에서는 댓글의 ID를 받아와 해당 ID의 댓글을 찾아와 삭제를 진행하도록 작성하였다. delete메서드는 JpaRepository에 있는 메서드를 상속받아 사용하였다.

 

HTML

<div class="card">
        <div class="card-header">
            댓글 리스트
            <span style="color:blue" th:if="${param.commentDelete}" th:text="'삭제되었습니다.'"></span>
            <span style="color:red" th:if="${param.commentDeleteFail}" th:text="'작성자만 삭제할 수 있습니다.'"></span>
            <ul id="comment--box" class="list-group">
                <tr th:each="comment : ${post.comment}">
                    <li id="comments--1" class="list-group-item d-flex justify-content-between">
                        <div th:text="${comment.contents}"></div>
                        <div class="d-flex">
                            <div class="font-italic" th:text="${comment.member.nickName}">
                            </div>
                            <button class="badge" th:onclick="|location.href='@{/comment/delete/{commentId}(commentId=${comment.id})}'|" type="button">삭제</button>
                        </div>
                    </li>
                </tr>
            </ul>
        </div>
    </div>

클라이언트 단에서는 삭제 버튼을 누르면 댓글의 ID를 파라미터로 물고 comment/delete/{commentId} 로 넘어갈 수 있도록 작성하였고 th:if="${param.xxx}"를 통해 댓글 삭제 완료 여부를 상태로 받아 클라이언트쪽에서 표기할 수 있도록 작성하였다.

 

이렇게 redirectattribue를 통해 상태를 파라미터로 전달하여 클라이언트 단을 조정 해보았는데 지금 수준의 프로젝트에서는 크게 문제가 되지 않을듯 보이지만, 페이지의 기능이 더 다양해질 수록 한계점이 있을 것으로 생각된다.

 

다음은 좋아요를 구현하여 게시물에 조회 및 좋아요를 표기할 예정이며

나아가 좋아요를 클릭한 게시물을 마이페이지에 저장하는 기능과

많은 좋아요를 받은 게시물을 리스트업하여 메인페이지에 뿌리는 기능을 개발보려고 한다.