다음의 순서는 댓글 기능에 대한 개요이다. 1번부터 5번까지는 백엔드 파트이고, 6번은 프론트엔드 파트이다.

 

1.댓글에 대한 DB테이블 생성(cno, bno, pcno, comment, commenter, reg_date, up_date)

   → cno는 댓글 번호, bno는 게시물 번호, pcno는 대댓글을 위한 기준 정렬 번호를 각각 의미한다.

 

2. Mapper XML 작성

3. DAO 작성 및 테스트

4. Service 작성 및 테스트

5. 컨트롤러 작성 및 테스트

6. UI 작성 및 테스트

 

게시판 CRUD와 같은 흐름의 방식으로 설계하기 때문에 1번~4번까지의 전반적인 내용은 생략하고, 5번 컨트롤러의 차이점을 중심으로 하여 정리하였다.

 

 

BoardController(게시판 컨트롤러)와의 설계 차이점


@PathVariable

 

쿼리스트링으로 들어가는 값과 Mapping 된 URI의 일부에 들어가는 값 인지를 잘 비교하고, Mapping 된 URI의 일부를 읽어올 때에는 앞에 @PathVariable을 붙여주어야 한다. 아래 예제 코드의 @DeleteMapping("/comments/{cno}") 처럼 URI의 일부에 들어가는 cno 값은 @PathVariable 붙여주어야 함을 볼 수 있다. 

 

@DeleteMapping("/comments/{cno}") // /comments/1?bno=729 <-- 삭제할 댓글 번호

public ResponseEntity<String> remove(@PathVariable Integer cno, Integer bno, HttpSession session) {
    String commenter = (String)session.getAttribute("id");

    try {
        int rowCnt = service.remove(cno, bno, commenter);

 

② ResponseEntity 객체

 

댓글 기능을 사용하던 중 에러가 발생하여 요청이 잘 처리되지 않았음에도 응답 헤더는 항상 200번대를 유지한다. 따라서 아래 예제 코드와 같이 요청이 잘 처리됐을 때와 처리되지 않았을 때에 따른 올바른 상태를 지정해주어야 한다. 이때 사용하는 것이 바로 ResponseEntity 객체이다.

 

try {
    int rowCnt = service.remove(cno, bno, commenter);

    if(rowCnt != 1)
        throw new Exception("Delete Failed");

    return new ResponseEntity<>("DEL_OK", HttpStatus.OK);
} catch (Exception e) {
    e.printStackTrace();
    return new ResponseEntity<>("DEL_ERR", HttpStatus.BAD_REQUEST);
}

 

③ RestController

 

메서드마다 일일이 @ResponseBody를 붙여주는 것 대신 클래스 앞에 @RestController 어노테이션을 사용하였다.

 

※ 간단 Tip) @RestController = @Controller + @ResponseBody

 

 

 

Ajax를 이용한 댓글 및 대댓글 기능 구현


아래 예제 코드는 댓글 기능 중 일부인 댓글 작성에 대한 코드이다. 전체적으로 각 댓글 버튼 UI를 구성하고 적절하게 각 버튼에 대한 클릭 이벤트를 작성해주어 댓글 기능들을 구현해준다.

 

ㆍtype : 요청 메서드

ㆍurl : 요청 URI

ㆍheaders : 요청 헤더(JSON)

ㆍdataType : 전송받을 데이터의 타입(생략하면 기본값이 JSON이 된다)

ㆍdata : 서버로 전송할 데이터이고, 따라서 직렬화(JSON 문자열로 변환)가 필요하다.

ㆍsuccess : 서버로부터 성공적으로 응답이 오면 호출되는 함수

ㆍerror : 에러가 발생하면 서버로부터 호출되는 함수

 

$("#sendBtn").click(function(){
    $.ajax({
        type:'POST',       // 요청 메서드
        url: '/ch4/send',  // 요청 URI
        headers : { "content-type": "application/json"}, // 요청 헤더
        dataType : 'text', // 전송받을 데이터의 타입
        data : JSON.stringify(person),  // 서버로 전송할 데이터. stringify()로 직렬화 필요.
        success : function(result){
            person2 = JSON.parse(result);    // 서버로부터 응답이 도착하면 호출될 함수
            alert("received="+result);       // result는 서버가 전송한 데이터
            $("#data").html("name="+person2.name+", age="+person2.age);
        },
        error   : function(){ alert("error") } // 에러가 발생했을 때, 호출될 함수
    }); // $.ajax()

 

댓글 기능을 구현하고 이를 바탕으로 특정 댓글에 대한 답글인 대댓글을 구현한다. 이때, 두 가지 사항을 고려한다.

 

1. '답글' 버튼을 누르면 대댓글을 작성할 해당 댓글의 바로 밑에 form 태그가 보여지도록 설계

 

  → .append($(this).parent())를 통해 각 해당 댓글 즉, 부모 댓글(li 태그) 뒤에 붙게 된다. 따라서 대댓글 입력 폼이 해당 댓글의 바로 밑에 보여지게 된다.

 

2. 댓글 DB테이블의 pcno 칼럼 정보를 통해 작성된 대댓글이 부모 댓글의 바로 밑에 위치하도록 설계

 

  → ORDER BY pcno asc, cno asc; 구문을 통해서 pcno를 기준으로 댓글 목록이 정렬될 수 있도록 하고, 여러 개의 대댓글이 달릴 수 있으므로 대댓글 또한 cno를 기준으로 정렬해주면 된다.

 

※ pcno에 부모 댓글 번호(cno) 값을 채워준다면 정렬 기준이 pcno이므로 부모 댓글 밑에 대댓글이 위치하게 되는 것

+ Recent posts