반응형
🤍Bootstrap으로 댓글창 디자인하기
- 댓글창은 당연히 글 상세조회 페이지에 필요하다. detail.jsp에 추가
<div class="card">
<form>
<input type="hidden" id="userId" >
<input type="hidden" id="boardId">
<div class="card-body">
<textarea id="reply-content" class="form-control" rows="1"></textarea>
</div>
<div class="card-footer">
<button id="btn-reply-save" class="btn btn-primary">등록</button>
</div>
</form>
</div>
🤍댓글 추가 기능 구현하기
- board.js에 버튼 클릭 이벤트를 작성한다.
let index = {
init: function() {
$("#btn-reply-save").on("click", () => {
this.replySave();
});
},
replySave: function() {
//alert('user의 save함수 호출됨');
let data = {
userId : $("#userId").val(),
boardId : $("#boardId").val(),
content: $("#reply-content").val()
};
console.log(data);
$.ajax({
//댓글쓰기 수행 요청
type: "POST",
url: `/api/board/${data.boardId}/reply`,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(function(resp) {
alert("댓글작성이 완료되었습니다.");
//console.log(resp);
location.href = `/board/${data.boardId}`;
}).fail(function(error) {
alert(JSON.stringify(error));
});
}
index.init();
- 컨트롤러 코드 작성
//데이터 받을 때 컨트롤러에서 dto를 만들어서 받는 게 좋다.
@PostMapping("/api/board/{boardId}/reply")
public ResponseDto<Integer> replySave(@RequestBody ReplySaveRequestDto replySaveRequestDto) {
boardService.댓글쓰기(replySaveRequestDto);
return new ResponseDto<Integer>(HttpStatus.OK.value(),1);
}
- ReplySaveRequestDto 작성
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReplySaveRequestDto {
private int userId;
private int boardId;
private String content;
}
- 서비스 계층 작성
@Transactional
public void 댓글쓰기(ReplySaveRequestDto replySaveRequestDto) {
int result = replyRepository.mSave(replySaveRequestDto.getUserId(), replySaveRequestDto.getBoardId(), replySaveRequestDto.getContent());
System.out.println("BoardService : "+result);
}
댓글 구현 완료
🤍댓글 목록 뿌리기
- 이미 Board 엔티티에 Reply가 존재하므로 간단하게 구현 가능함.
- 그런데 무한 참조를 방지하기 위해 @JsonIgnoreProperties({"board"})를 추가해 준다.
@OneToMany(mappedBy = "board", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
@JsonIgnoreProperties({"board"})
@OrderBy("id desc")
private List<Reply> replys;
- detail.jsp에 댓글 목록 추가
<div class="card">
<div class="card-header">댓글 리스트</div>
<ul id="reply-box" class="list-group">
<c:forEach var="reply" items="${board.replys}">
<li id="reply-${reply.id}" class="list-group-item d-flex justify-content-between">
<div>${reply.content}</div>
<div class="d-flex">
<div class="font-italic">작성자 : ${reply.user.username} </div>
</div>
</li>
</c:forEach>
</ul>
</div>
테스트용으로 DB에 댓글 3개를 넣어준 뒤
화면을 조회해 보면 댓글 목록이 잘 출력되는 것을 확인할 수 있다.
🤍댓글 삭제 기능 구현하기
- detail.jsp에 댓글 삭제 버튼을 추가한다. 단!! 댓글 작성자에게만 삭제 버튼이 출력되도록 조건문 추가.
<c:if test="${reply.user.id eq principal.user.id}">
<button onClick="index.replyDelete(${board.id}, ${reply.id})" class="badge">삭제</button>
</c:if>
- 댓글 삭제 함수 추가
replyDelete : function(boardId, replyId){
$.ajax({
type: "DELETE",
url: `/api/board/${boardId}/reply/${replyId}`,
dataType: "json"
}).done(function(resp){
alert("댓글삭제 성공");
location.href = `/board/${boardId}`;
}).fail(function(error){
alert(JSON.stringify(error));
});
}
- 댓글 삭제 코드는 매우 간단하다.
@Transactional
public void 댓글삭제(int replyId) {
replyRepository.deleteById(replyId);
}
@DeleteMapping("/api/board/{boardId}/reply/{replyId}")
public ResponseDto<Integer> replyDelete(@PathVariable int replyId){
boardService.댓글삭제(replyId);
return new ResponseDto<Integer>(HttpStatus.OK.value(),1);
}
작성자 본인에게만 삭제 버튼이 보이고
삭제 기능 구현까지 완료
댓글 기능까지 해서 스프링부트 블로그 만들기 프로젝트가 끝이 났다!!! 커밋까지 완료!
반응형
'💻 my code archive > 🏷️JAVA & Spring(Boot)' 카테고리의 다른 글
프로젝트 #1 스프링부트 SpringBoot 3x Swagger 적용법 (1) | 2024.04.20 |
---|---|
SheetJS 테이블 내용 엑셀 다운로드, 스타일 적용 방법 (0) | 2023.08.18 |
[스프링부트 블로그 만들기] 카카오 로그인 API 서비스 구현하기 (0) | 2022.03.25 |
[스프링부트 블로그 만들기] 회원 정보 수정 구현하기 (0) | 2022.03.24 |
스프링부트 공부기록(32) - API 서비스 만들기 (0) | 2022.03.21 |