detail.html

댓글 등록 폼을 생성해줍니다.

<div class="card" style="margin-bottom: 1rem;">
    <div class="card-body"><textarea id="reply-content" class="form-control-plaintext" placeholder="댓글을 작성하세요." rows="1"></textarea></div>
    <div class="card-footer">
        <button type="button" id="btn-reply-save" class="btn btn-primary">등록</button>
    </div>
</div>

board.js

btn-reply-save 버튼을 클릭 했을 때 동작할 코드를 작성해줍니다.

reply-content id를 가진 태그의 값을 가져와 content에 저장하고 HttpBody에 Json형식으로 담아 /api/board/${boardId}/reply 주소로 POST 요청을 보냅니다.

replySave: function () {
    let data = {
        content: $("#reply-content").val()
    }

    $.ajax({
        type: "POST",
        url: `/api/board/${boardId}/reply`,
        data: JSON.stringify(data),
        contentType: "application/json; charset=utf-8",
        dataType: "json",

    }).done(function (response) {
        // 요청 결과가 정상인 경우
        const status = response.status;

        if (status === 200){
            alert("댓글 등록이 완료 되었습니다.");
            location.href = ("/board/" + boardId);
        } else {
            alert(response.data);
        }

    }).fail(function (error) {
        // 요청 결과가 비정상인 경우
        alert(JSON.stringify(error));

    });
},

BoardApiController.java

댓글 등록 요청에 응답할 컨트롤러 메서드를 생성합니다.

@PostMapping("/api/board/{id}/reply")
public ResponseDTO<Integer> replySave(@PathVariable int id,
                                      @RequestBody Reply reply,
                                      @AuthenticationPrincipal PrincipalDetail principalDetail){

    boardService.replySave(principalDetail.getUser(), id, reply);
    return new ResponseDTO<>(HttpStatus.OK.value(), 1);
}

파라미터

BoardService.java

Reply 객체에 Board, User 객체를 저장하고 DB에 저장해줍니다.

@Transactional
public void replySave(User user, int boardId, Reply requestReply) {
    Board board = boardRepository.findById(boardId).orElseThrow(() -> {
        throw new IllegalArgumentException("댓글 등록 실패: 게시글 id를 찾을 수 없습니다.");
    });
    requestReply.setUser(user);
    requestReply.setBoard(board);

    replyRepository.save(requestReply);
}