Spring Boot JPA 게시판 댓글 작성자만 수정, 삭제 가능하게 하기
by coco3o이전 포스팅에 이어서 댓글 수정, 삭제는 댓글 작성자만 가능하게 구현한 내용을 포스팅 하겠다.
Spring Boot JPA 게시판 댓글기능 구현 - 댓글 수정 및 삭제
지난 포스팅에 이어 댓글 수정 및 삭제 기능을 구현하도록 하겠다. Spring Boot JPA 게시판 댓글기능 구현하기 - 댓글 작성 및 조회 게시판에서 댓글은 없어선 안될 중요한 부분이라고 생각한다. 그
dev-coco.tistory.com
필자는 이번 파트를 구현하면서 상당한 고역을 겪었다. 일단 구현내용부터보고 마저 얘기하도록 하자.
1. Controller
PostsIndexController
@RequiredArgsConstructor @Controller public class PostsIndexController { private final PostsService postsService; ... /* 글 상세보기 */ @GetMapping("/posts/read/{id}") public String read(@PathVariable Long id, @LoginUser UserSessionDto user, Model model) { PostsResponseDto dto = postsService.findById(id); List<CommentResponseDto> comments = dto.getComments(); /* 댓글 리스트 */ if (comments != null && !comments.isEmpty()) { model.addAttribute("comments", comments); } /* 사용자 관련 */ if (user != null) { model.addAttribute("user", user); /* 게시글 작성자 본인인지 확인 */ if (dto.getUserId().equals(user.getId())) { model.addAttribute("writer", true); } /* 댓글 작성자 본인인지 확인 */ for (int i = 0; i < comments.size(); i++) { //댓글 작성자 id와 현재 사용자 id를 비교해 true/false 판단 boolean isWriter = comments.get(i).getUserId().equals(user.getId()); log.info("isWriter? : " + isWriter); model.addAttribute("isWriter",isWriter); } } postsService.updateView(id); // views ++ model.addAttribute("posts", dto); return "posts/posts-read"; } }
2. Mustache
comment/list.mustache
{{! Comments }} <div class="card"> <div class="card-header bi bi-chat-dots"> {{#comments.size}}{{comments.size}}{{/comments.size}} Comments</div> {{! 댓글내용 부분 }} <ul class="list-group-flush"> {{#comments}} <li id="comments-{{id}}" class="list-group-item"> <span> <span style="font-size: small">{{nickname}}</span> <span style="font-size: xx-small">{{createdDate}}</span> </span> {{#isWriter}} <a type="button" data-toggle="collapse" data-target=".multi-collapse-{{id}}" class="bi bi-pencil-square"></a> {{! 댓글 수정 버튼 }} <a type="button" onclick="main.commentDelete({{postsId}},{{id}},{{userId}},{{user.id}})" class="bi bi-x-square"></a> {{! 댓글 삭제 버튼 }} {{/isWriter}} {{! 댓글 내용 보기 }} <p class="collapse multi-collapse-{{id}} show">{{comment}}</p> {{! 댓글 내용 수정 }} <form class="collapse multi-collapse-{{id}}"> <input type="hidden" id="id" value="{{id}}"> <input type="hidden" id="postsId" value="{{postsId}}"> <input type="hidden" id="writerUserId" value="{{userId}}"> <input type="hidden" id="sessionUserId" value="{{#user}}{{user.id}}{{/user}}"> <div class="form-group"> <textarea class="form-control" id="comment-content" rows="3">{{comment}}</textarea> </div> <button type="button" id="btn-comment-update" class="btn btn-outline-primary bi bi-pencil-square"> 수정</button> </form> </li> {{/comments}} </ul> </div>
수정폼과 삭제버튼에 댓글작성자id 번호와 현재 사용자(세션)id 번호를 받아 넘겨줬다.
3. app.js
/** 댓글 수정 */ commentUpdate : function (form) { const data = { id: form.querySelector('#id').value, postsId: form.querySelector('#postsId').value, comment: form.querySelector('#comment-content').value, writerUserId: form.querySelector('#writerUserId').value, sessionUserId: form.querySelector('#sessionUserId').value } console.log("commentWriterID : " + data.writerUserId); console.log("sessionUserID : " + data.sessionUserId); if (data.writerUserId !== data.sessionUserId) { alert("본인이 작성한 댓글만 수정 가능합니다."); return false; } if (!data.comment || data.comment.trim() === "") { alert("공백 또는 입력하지 않은 부분이 있습니다."); return false; } const con_check = confirm("수정하시겠습니까?"); if (con_check === true) { $.ajax({ type: 'PUT', url: '/api/posts/' + data.postsId + '/comments/' + data.id, dataType: 'JSON', contentType: 'application/json; charset=utf-8', data: JSON.stringify(data) }).done(function () { window.location.reload(); }).fail(function (error) { alert(JSON.stringify(error)); }); } }, /** 댓글 삭제 */ commentDelete : function (postsId, commentId, commentWriterId, sessionUserId) { // 본인이 작성한 글인지 확인 if (commentWriterId !== sessionUserId) { alert("본인이 작성한 댓글만 삭제 가능합니다."); } else { const con_check = confirm("삭제하시겠습니까?"); if (con_check === true) { $.ajax({ type: 'DELETE', url: '/api/posts/' + postsId + '/comments/' + commentId, dataType: 'JSON', }).done(function () { alert('댓글이 삭제되었습니다.'); window.location.reload(); }).fail(function (error) { alert(JSON.stringify(error)); }); } } }
댓글작성자id와 현재사용자id를 비교해 작성자가 아니면 댓글 수정 및 삭제하지 못하도록 후처리를 해주었다.
4. 결과 확인


여기까지는 문제가 없지만, 다음 그림을 보자.

다른 사용자의 댓글까지 수정/삭제 버튼이 보인다.
mustache는 단순히 화면에 데이터를 렌더링 하는 엔진이다.
Logic-less하고 true/false 여부만 판단하며, 항상 최종값만 넘겨받기 때문에, 부분적으로 true/false를 줄 방법은 없었다.
그래서 댓글란에 자신의 댓글이 존재하면 다른 사용자의 댓글이 있어도 true를 리턴해 전체 댓글에 버튼이 보이는 것이였다.
thymeleaf였으면 if문으로 간단히 할 수 있을텐데
부분적으로 버튼을 보여줄 다른 방법이 없을까 몇 날 며칠을 고민해봤으나 결국 찾지 못했고, 자바스크립트로 후처리를 해줬다.
프로젝트를 완성하고 thymeleaf로 조금씩 바꾸면서 완성도를 더 높여야겠다.


블로그의 정보
슬기로운 개발생활
coco3o