Christmas Pikachu spring boot 댓글 삭제기능
개발일지/스프링

spring boot 댓글 삭제기능

ZI_CO 2022. 12. 19.

detail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="../layout/header.jsp"%>


<div class="container">

	<button class="btn bg-secondary" onclick="history.back();">돌아가기</button>
	<c:if test="${board.user.id == principal.user.id }">
		<a class="btn btn-warning" id="" href="/board/${board.id}/update_form">수정</a>
		<button class="btn btn-danger" id="btn--delete">삭제</button>
	</c:if>



	<br /> <br /> <br />

	<div>
		<input type="hidden" id="board-id" value="${board.id}"> 글 번호 : <span><i>${board.id + 100}</i> </span>
	</div>
	<div>
		글 작성자 : <span> ${board.user.username}</span>
	</div>
	<br /> <br /> <br />

	<div class="">
		<h3>${board.title}</h3>
	</div>

	<div>${board.content}</div>
	<br /> <br />
	<div class="card">
		<div class="card-body">
			<textarea rows="1" class="form-control" id="content"></textarea>

		</div>
		<div class="card-footer">
			<button class="btn btn-primary" id="btn-reply-save">등록</button>
		</div>
	</div>
	<br />
	<div class="card">
		<div class="card-header">댓글 목록</div>
	</div>
	<c:forEach var="reply" items="${board.replys}">
		<ul class="list-group">
			<li class="list-group-item d-flex justify-content-between">
				<div>${reply.content}</div>
				<div class="d-flex">
					<div>작성자 :&nbsp; &nbsp;[ ${reply.user.username} ] &nbsp; &nbsp;</div>
					<c:if tes`t="${reply.user.id eq principal.user.id }">
						<button class="btn btn-danger badge" onclick="index.replyDelete(${board.id}, ${reply.id});">삭제</button>
					</c:if>
			</li>
		</ul>
	</c:forEach>
</div>

<script src="/js/board.js"></script>
<%@ include file="../layout/footer.jsp"%>

 

 

 

 

 

board.js

let index = {
	init: function() {
		$("#btn--save").bind("click", () => {
			this.save();
		});

		$("#btn--delete").bind("click", () => {
			this.deleteById();
		});

		$("#btn--update").bind("click", () => {
			this.update();
		});

		$("#btn-reply-save").bind("click", () => {
			this.replySave();
		});

	},
	save: function() {
		let xcheckTitle = XSSCheck($("#title").val());
		
		let data = {
			title: xcheckTitle,
			content: $("#content").val()
		};

		// ajax 통신 요청 
		$.ajax({
			type: "POST",
			url: "/api/board",
			data: JSON.stringify(data),
			contentType: "application/json; charset=utf-8",
			dataType: "json"
		}).done(function(data, textSatus, xhr) {
			if (data.status == "OK") {
				alert("글쓰기 성공");
				location.href = "/";
			}
		}).fail((error) => {
			console.log(error);
			alert(error.responseJSON.error);

		});

	},
	deleteById: function() {
		let id = $("#board-id").val();
		// 통신 ---> ajax 
		$.ajax({
			type: "DELETE",
			url: "/api/board/" + id
		}).done(function(data, textStatus, xhr) {
			if (data.status == "OK") {
				alert("글 삭제가 완료 되었습니다");
				location.href = "/";
			}
		}).fail(function(error) {
			alert("글 삭제하기에 실패 하였습니다");
		});
	},
	update: function() {
		// HTML 태그에 직접 속성을 정의할 수 있다. 규칙은 data-* 
		// data-* 값을 가지고 오기 위해서 Jquery --> (선택자).attr("data-[id]")
		let boardId = $("#board-id").attr("data-id");

		let data = {
			title: $("#title").val(),
			content: $("#content").val()
		}

		$.ajax({
			type: "PUT",
			url: "/api/board/" + boardId,
			data: JSON.stringify(data),
			contentType: "application/json; charset=utf-8",
			dataType: "json"
		}).done(function(data, textStatus, xhr) {
			if (data.status) {
				alert("글 수정이 완료 되었습니다");
				location.href = "/";
			}
		}).fail(function(error) {
			console.log(error);
			alert("글 수정에 실패 하였습니다");
		});

	},
	replySave: function() {

		let replydata = {
			boardId: $("#board-id").val(), // fk (board pk) 
			content: $("#content").val()
		};
		// ajax 통신 요청 
		$.ajax({
			type: "POST",
			url: `/api/board/${replydata.boardId}/reply`,
			data: JSON.stringify(replydata),
			contentType: "application/json; charset=utf-8",
			dataType: "json"
		}).done(function(data, textSatus, xhr) {
			if (data.status == "OK") {
				alert("댓글작성이 완료 되었습니다.");
				location.href = `/board/${replydata.boardId}`;
			}
		}).fail((error) => {
			console.log(error);
			alert("댓글 작성에 실패 하였습니다.");
		});

	},

	replyDelete: function(boardId, replyId) {
		$.ajax({
			type: "DELETE",
			url: `/api/board/${boardId}/reply/${replyId}`,
			dataType: "json"
		}).done(function(resData) {
			if(resData.status == "OK") {
				alert("댓글 삭제 성공");
				location.href = `/board/${boardId}`
			}
		}).fail(function(error) {
				alert("댓글 삭제 실패");
		});
	}
}

function XSSCheck(str, level) {
    if (level == undefined || level == 0) {
        str = str.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g,"");
    } else if (level != undefined && level == 1) {
        str = str.replace(/\</g, "&lt;");
        str = str.replace(/\>/g, "&gt;");
    }
    return str;
}



index.init();

 

 

 

 

 

 

 

BoardApiControlller

댓글을 삭제할때 매개변수로 접근주체의 세션값, 게시글Id, 댓글Id를 매개변수로 받아와서

Service에서 삭제기능(메소드)를 만들어 매개변수에 댓글Id, 세션에접근하여 유저의 Id값으로 댓글을 삭제처리 해주면 된다.

@DeleteMapping("/api/board/{boardId}/reply/{replyId}")
	public ResponseDto<?> deleteReplyById(@PathVariable String boardId, @PathVariable int replyId,
			@AuthenticationPrincipal PrincipalDetail principalDetail) {
		// 서비스 요청 처리

		// 검증 (현재 삭제 요청자, db 저장된 사용자 id 역시 비교해서 처리를 해주어야 한다.)

		try {
			boardService.deleteReplyById(replyId, principalDetail.getUser().getId());

		} catch (Exception e) {
			// TODO: handle exception
		}
		return new ResponseDto<Integer>(HttpStatus.OK, 1);
	}

 

 

 

 

 

 

 

BoardService 

삭제기능에 필요한것은 먼저 어떤 댓글인지 알기위해 매개변수로 댓글Id와, 유저의Id값을 넣준다.

Repository에서 먼저 findById메소드를 사용하여 replyId값을 select후 replyEntity변수에 담아예외처리까지 해준다.

ReplyId를 조회했으면 db에 저장되어있는 reply작성자의 유저Id와 매개변수로 담아준 유저Id값을 각각 변수에담아준다.

그리고나서 db에 저장되어있는 리플작성자와 매개변수로 넘어올 유저Id값이 같을시!!! 즉 본인이 전에 작성했던 댓글과

로그인해서 세션에 등록되어있는 유저의 정보를 비교를하여 같으면 댓글Id값으로 삭제해주면된다.

 

	@Transactional
	public void deleteReplyById(int replyId, int requestUserId) {
		System.out.println("requestUserId " + requestUserId);

		Reply replyEntity = replyRepostiory.findById(replyId).orElseThrow(() -> {
			return new IllegalArgumentException("해당글을 찾을수 없음");
		});
		try {
			int dbWrite = replyEntity.getUser().getId();
			int principalId = requestUserId;

			if (dbWrite == principalId) {
				replyRepostiory.deleteById(replyId);
			} else {
				throw new IllegalArgumentException("해당글을 찾을수 없음");
			}
		} catch (Exception e) {
		}
	}

 

댓글