티스토리 뷰

반응형

댓글 달기 로직

  1. 로그인이 되어 있고 게시물이 존재한다면 댓글 달기 화면으로 넘긴다(자신이 누구의 게시물에 댓글을 다는지 알려준다)
  2. 유저는 댓글 내용만 입력할 수 있고 자신이 댓글을 달 게시물을 볼 수 있다.
  3. 입력한 내용을 컨트롤러가 CommentPostDTO로 받아온다.
  4. 컨트롤러는 로그인이 되어 있는지, 댓글을 달 게시물이 존재하는지, 댓글을 다는 유저가 존재하는지를 검사
  5. 위의 조건을 모두 만족시키면 commentService를 이용해 댓글을 Comment DB에 저장

✏️ Comment 클래스

@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "idx", nullable = false)
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "boardIdx", nullable = false)
    private Board boardIdx;

    @Column(name = "content", nullable = false, length = 20)
    private String content;

    @Column(name = "memberId", nullable = false)
    private String memberId;

}

Comment DB 구조와 동일하다


✏️ CommentPostDTO

@Getter
@Setter
@Builder
public class CommentPostDTO {
    private String content;
}

입력받는 댓글 내용을 컨트롤러로 전달한다.


✏️ comment.html 생성

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" th:href="@{/css/main.css}">
    <title>댓글 달기</title>
</head>
<body>
<h1><span th:text="${user}"></span>님 게시물에 댓글 달기</h1>
<table class="table">
    <thead class="thead-light">
    <tr class="text-center">
        <th scope="col">글번호</th>
        <th scope="col">글제목</th>
        <th scope="col">내용</th>
        <th scope="col">작성자</th>
    </tr>
    </thead>
    <tbody>
        <tr th:each="board : ${board}">
            <td scope="row" width="10%">
                <input th:type="text" th:value="${board.idx}" readonly>
            </td>
            <td scope="row" width="20%">
                <input th:type="text" th:value="${board.title}" readonly>
            </td>
            <td scope="row" width="10%">
                <input th:type="text" th:value="${board.content}" readonly>
            </td>
            <td scope="row" width="10%">
                <input th:type="text" th:value="${board.member.id}" readonly>
            </td>
        </tr>
    </tbody>
</table>
<form method="post" th:action="${'/member/comment/' + board.idx + '/post'}" class="login-box">
    <table id="login-table">
        <tr>
            <td><label>내용<textarea cols="50" rows="10" name="content"></textarea></label></td>
        </tr>

        <tr>
            <td>
                <input type="submit" value="등록">
            </td>
        </tr>
    </table>
</form>
</body>
</html>

 


✏️ Api Controller 클래스

@PostMapping("/comment/{idx}/post")
public String commentPost(@PathVariable("idx") Integer idx, CommentPostDTO postDTO, HttpServletRequest
        httpServletRequest) {

    HttpSession session = httpServletRequest.getSession(false);
    Optional<Object> idOptional = Optional.ofNullable(session.getAttribute("userId"));
    if (idOptional.isEmpty()) {
        log.error("권한 없음");
        return "redirect:/member/login";
    }
    String id = idOptional.get().toString();
    boolean isBoardExistCheck = boardService.checkBoardExist(idx.longValue());
    if (!isBoardExistCheck) {
        log.error("게시물이 존재하지 않음");
        return "redirect:/member/list";
    }

    boolean isMemberExist = memberService.checkMemberExist(id);
    if (!isMemberExist) {
        log.error("권한이 없습니다.");
        return "redirect:/member/login";
    }

    commentService.save(postDTO, id, idx);
    log.info("댓글 업로드");
    return "redirect:/member/list";
}

로그인이 되어 있는지 검사 후 로그인 상태가 아니라면 로그인 화면으로 이동시킨다

idx를 가진 게시물이 있는지 검사 후 없다면 메인 화면으로 이동시킨다.

세션에서 얻은 id를 통해 Member에 있는 id 있는지 검사 후 없다면 로그인 화면으로 이동시킨다

위의 조건을 다 만족시키면 commentService를 통해 댓글을 Comment DB에 저장한다.


✏️ WebController 클래스

@GetMapping("/member/comment/{idx}")
public String comment(@PathVariable("idx") int idx, Model model, HttpServletRequest httpServletRequest) {

    Optional<Board>boardOptional = boardService.getBoardByIdx(idx);
    if(boardOptional.isEmpty()){
        log.error("존재하지 않음");
        return "redirect:/member/list";
    }
    Board board = boardOptional.get();
    HttpSession session = httpServletRequest.getSession();
    Optional<Object> idOptional = Optional.ofNullable(session.getAttribute("userId"));
    if(idOptional.isEmpty()){
        log.error("권한 없음");
        return "redirect:/member/login";
    }
    String author = idOptional.get().toString();

    model.addAttribute("board",board);
    model.addAttribute("user",board.getMember().getId());
    model.addAttribute("author",author);
    return "comment";
}

idx를 통해 게시글이 있는지 검사하고 없다면 메인 화면으로 이동시킨다

로그인이 되어 있지 않다면 로그인 화면으로 이동시킨다

위 조건을 모두 만족시킨다면 comment.html에 게시물과, 게시물 작성자, 댓글 작성자를 넘겨준다


✏️ CommentRepository 인터페이스

public interface CommentRepository extends JpaRepository<Comment, Integer> {
    void deleteByBoardIdx(Board board);
}

쿼리문을 추가한다


✏️ CommentService 인터페이스

public interface CommentService {
    void save(CommentPostDTO postDTO,String id,Integer idx);
}

✏️ CommentServiceImpl 클래스

@Service
@RequiredArgsConstructor
public class CommentServiceImp implements CommentService {

    private final CommentRepository commentRepository;
    private final BoardRepository boardRepository;

    @Override
    public void save(CommentPostDTO postDTO,String id, Integer idx) {
        Optional<Board>boardOptional = boardRepository.findById(idx.longValue());
        Comment comment = Comment.builder()
                        .boardIdx(boardOptional.get()).content(postDTO.getContent()).memberId(id).build();
        commentRepository.save(comment);
    }
}

컨트롤러로부터 넘겨받은 idx를 통해 게시물을 가져온다. 사실 여기서도 Board가 존재한다면 Comment를 구현하는게 정확하지만 컨트롤러에서 이미 검사를 다 하고 가져와서 생략했음


✏️ checkBoardExist 메소드(BoardService에 존재)

@Override
public boolean checkBoardExist(Long idx) {
    Optional<Board> board = boardRepository.findById(idx);
    if (board.isEmpty()) { // 존재하지 않음
        return false;
    } else // 존재함
        return true;
}

✏️ checkMemberExist 메소드 (MemberService에 존재)

 @Override
  public boolean checkMemberExist(String id) {
      Optional<Member> memberOptional = memberRepository.findById(id);
      if(memberOptional.isPresent()){
          log.error("동일한 아이디가 존재");
          return true;
      }
      else {
          log.info("동일한 아이디 없음");
          return false;
      }
  }

댓글 보기 로직

  1. 로그인이 되어 있는지 검사하고, idx를 통해 게시물의 존재 여부를 검사
  2. 위의 조건을 모두 만족시킨다면 commentService를 통해 그 게시물에 달려 있는 댓글을 모두 comments로 받아옴
  3. 컨트롤러는 view.html에 comments와 게시물을 넘겨준다

✏️ view.html 생성

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" th:href="@{/css/main.css}">
    <title>댓글 보기</title>
</head>
<body>
<table class="table">
    <thead class="thead-light">
    <tr class="text-center">
        <th scope="col">글번호</th>
        <th scope="col">글제목</th>
        <th scope="col">내용</th>
        <th scope="col">작성자</th>
        <th scope="col">좋아요</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="board : ${board}">
        <td scope="row" width="10%">
            <div th:text="${board.idx}" th:name="idx"></div>
        </td>
        <td scope="row" width="20%">
            <div th:text="${board.title}"></div>
        </td>
        <td scope="row" width="10%">
            <div th:text="${board.content}"></div>
        </td>
        <td scope="row" width="10%">
            <div th:text="${board.member.id}"></div>
        </td>
        <td>
            <div th:text="${board.likeCount}"></div>
        </td>
    </tr>
    </tbody>
</table>
<table class="table">
    <thead class="thead-light">
    <tr class="text-center">
        <th scope="col">댓글번호</th>
        <th scope="col">게시물번호</th>
        <th scope="col">내용</th>
        <th scope="col">작성자</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="comment : ${comments}">
        <td scope="row" width="10%">
            <div th:text="${comment.id}"></div>
        </td>
        <td scope="row" width="20%">
            <div th:text="${comment.boardIdx.idx}"></div>
        </td>
        <td scope="row" width="10%">
            <div th:text="${comment.content}"></div>
        </td>
        <td scope="row" width="10%">
            <div th:text="${comment.memberId}"></div>
        </td>
    </tr>
    </tbody>
</table>
</body>
</html>

✏️ WebController 클래스

 
@GetMapping("/member/comment/{idx}/view")
public String viewComment(@PathVariable("idx") int idx, Model model, HttpServletRequest httpServletRequest) {
		HttpSession session = httpServletRequest.getSession();
		Optional<Object> idOptional = Optional.ofNullable(session.getAttribute("userId"));
		if(idOptional.isEmpty()){
		    log.error("권한 없음");
		    return "redirect:/member/login";
		}
		
		Optional<Board>boardOptional = boardService.getBoardByIdx(idx);
		if(boardOptional.isEmpty()){
		    log.error("존재하지 않음");
		    return "redirect:/member/list";
		}
		Board board = boardOptional.get();
		log.error(board.toString());
		List<Comment> comments = commentService.getCommentList(board);
		
		model.addAttribute("comments", comments);
		model.addAttribute("board", board);
		return "view";
}

먼저 로그인이 되어 있는지를 검사한다.

그 다음 전달받은 idx를 통해 게시물이 있는지 검사한다.

위의 두 조건을 만족시킨다면 commentService를 통해 댓글 리스트를 모두 가져온다

view.html에 게시물과 댓글 리스트를 전달 해준다.


✏️ CommentRepository 인터페이스

List<Comment> findByBoardIdx(Board board);

게시물의 번호를 통해 댓글 리스트를 가져온다(한 게시물에는 여러 개의 댓글이 달릴 수 있으므로 List로 리턴)


✏️ CommentService 인터페이스

List<Comment> getCommentList(Board board);

✏️ CommentServiceImp 클래스

@Override
public List<Comment> getCommentList(Board board) {
    return commentRepository.findByBoardIdx(board);
}

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함