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로 조금씩 바꾸면서 완성도를 더 높여야겠다.
'📌ETC > Development Log' 카테고리의 다른 글
대용량 엑셀 다운로드 OOM(Out Of Memory) 해결 과정 (5) | 2024.08.16 |
---|---|
DTO Inner Class로 한번에 관리하기 (2) | 2022.01.13 |
Spring Boot JPA 게시판 댓글 수정 및 삭제 구현하기 (3) | 2022.01.08 |
Spring Boot JPA 게시판 댓글 작성 및 조회 구현하기 (2) | 2022.01.04 |
Spring Boot 게시판 JPA 연관관계 매핑으로 글 작성자만 수정, 삭제 가능하게 하기 (0) | 2021.12.30 |
블로그의 정보
슬기로운 개발생활
coco3o