Spring/Spring 공부

[BEWITHME/SPRING] 댓글 기능 - 작성 (저장)

congs 2023. 7. 18. 21:46

 

게시글 하단에 댓글 기능 추가 : 댓글 저장

 


-- 위치 ( Com_Comment.jsp : 게시글  ) --

  • 게시글 부분 = 동기 출력, 댓글 = 비동기 출력
  • ↓ 최종 완성된 jsp (저장,출력,수정,삭제)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/resources/css/com_comment.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
    
<title>com_comment</title>
</head>
<body>

  
    <div class="container">
        
        <!-- 좌측/ 전체 동일한 메뉴바 부분 -->
       <div class="left">
           <img src="/resources/img/logo.png" class="logo" alt="">
           <div class="menu_bar">
               <button><a href=""> 🏠<span> Home</span></a></button><br>
               <button><a href="">📝<span> Subject</span></a></button><br>
               <button><a href="/community/communitypage">📖<span class="not"> Community</span></a></button><br>
               <button><a href="">📁<span> Q&A</span></a></button><br>
            </div>
            <div class="sebu">
                <button><a href="">⚙ Setting</a></button><br>
                <button><a href="">🗑 Log out</a></button><br>
            </div>
        </div>
        <!-- 우측/ Comment 부분 -->
        <div class="right">
            
            <!-- 고정/ 메뉴 선택 -->
            <div class="nav_bar">
                <div class="nav">
                    <button> 전체 </button>
                    <button> 개발 </button>
                    <button> 상담 </button>
                    <button> MY </button>
                </div>
                <a href="#" class="question">
                    <button>💡 질문하기</button>
                </a>
            </div>
            <div class="nav_line"></div>
            
            
            <!-- 스크롤/ 게시글, 댓글 출력 -->
            <div class="main">  
                
                <a href="#end" id="top"></a>
                
                <!-- 게시글 -->
                <c:set var="cvo" value="${cvo}"></c:set>
                <div class="board">
                    <div class="board_header">
                        <p>${cvo.com_category}</p>
                        <h1 class="title">${cvo.com_title}</h1>
                        <div class="writer">${cvo.nickname}</div>
                        <div class="reaction">
                            <div class="reaction_left">
                                <span>${cvo.com_reg_date} |</span>
                                <span>
                                    <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-chat" viewBox="0 0 16 16">
                                        <path d="M2.678 11.894a1 1 0 0 1 .287.801 10.97 10.97 0 0 1-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 0 1 .71-.074A8.06 8.06 0 0 0 8 14c3.996 0 7-2.807 7-6 0-3.192-3.004-6-7-6S1 4.808 1 8c0 1.468.617 2.83 1.678 3.894zm-.493 3.905a21.682 21.682 0 0 1-.713.129c-.2.032-.352-.176-.273-.362a9.68 9.68 0 0 0 .244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9.06 9.06 0 0 1-2.347-.306c-.52.263-1.639.742-3.468 1.105z"/>
                                    </svg> ${comment_cnt} |
                                </span>
                                <span>
                                    <svg xmlns="http://www.w3.org/2000/svg" width="13" height="12" fill="currentColor" class="bi bi-suit-heart-fill" viewBox="0 0 16 16">
                                        <path d="M4 1c2.21 0 4 1.755 4 3.92C8 2.755 9.79 1 12 1s4 1.755 4 3.92c0 3.263-3.234 4.414-7.608 9.608a.513.513 0 0 1-.784 0C3.234 9.334 0 8.183 0 4.92 0 2.755 1.79 1 4 1z"/>
                                    </svg> ${cvo.com_like_cnt}
                                </span>
                            </div>
                            <div class="reaction_right">
                                <svg xmlns="http://www.w3.org/2000/svg" width="18" height="13" fill="currentColor" class="bi bi-eye-fill" viewBox="0 0 16 16">
                                    <path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/>
                                    <path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/>
                                </svg>
                                  ${cvo.com_cnt}
                            </div>
                        </div>
                    </div><!--class="board_header"-->

                    <div class="line"></div>

                    <div class="board_content">
                        ${cvo.com_content}
                    </div><!--class="board_content"-->

                    <div class="board_footer">
                        <!-- 이전글/ 다음글 -->
                        
                    </div>

                    <div class="line"></div>
                    
                </div><!--class="board"-->
                
                <!-- 해당 댓글 -->
                <div class="comment">

                    <div class="comment_count">
                        댓글 <span>${comment_cnt}</span>
                    </div>

                    <!--작성부분-->
                    <div class="comment_write">
                        <textarea placeholder="내용을 입력해 주세요." maxlength="500" wrap="soft" id="com_com_content"></textarea>
                        <div class="cw_line"></div>
                        <div>
                            <span>{ses.nickname}</span>
                            <button type="submit" id="subBtn">작성하기</button>
                        </div>
                    </div>

                    <div class="comment_list" id="comment_list">
                    <!--댓글리스트 출력부분-->
                    </div>

                </div><!--class="comment"-->
                
            </div><!--class="main"-->
            
            <div class="up">
                <a href="#top" id="end"> 
                    <span class="material-symbols-outlined">
                            arrow_upward
                    </span>
                </a>
            </div>

        </div><!--class="right"-->

</div>


<script type="text/javascript" src="/resources/js/com_comment.js"></script>
<script type="text/javascript">
	const com_num = '<c:out value="${cvo.com_num}" />';
	getCommentList(com_num)
</script>

</body>
</html>

 


 

--  필요한 class, xml 파일 생성/연결 --

 

  1. src/main.java > package
    1. controller : Com_CommentController.class
    2. domain : Com_CommentVO.class
    3. service: Com_CommentService.class
    4. serviceImpl: Com_CommentServiceImpl.class
    5. dao: Com_CommentDAO.xml
  2. src/main.resources > mappers
    1. mapper: Com_CommentMapper.xml
  3. src > main > webapp > resources > js
    1. JS: com_comment.js

 

 

 

 


 

-- 댓글 저장 --

 

1. com_comment.js 작성

- 작성 내용 controller로 전송

  1. 댓글 작성 후 '작성하기' 버튼을 클릭하면 저장 이벤트가 발생하도록 설정
  2. 해당 댓글의 작성내용과 게시글번호를 cmtData객체에 담기 
    1. 해당 댓글의 작성내용(com_com_content)을 getElementById로 가져오고
    2. jsp에서 설정한 해당 게시글 번호(com_num)을 가져와서 담기
  3. cmtData를 비동기로 Com_CommentController에 보내기

-  화면에 출력 이벤트

  1. DB에 댓글 저장 성공시, alter로 '댓글 저장 성공' 화면에 출력
  2. 댓글 내용 미작성시, 댓글 작성부분 focus효과 및 '댓글을 입력해주세요' 화면에 출력
// -- 댓글 저장 --
async function insertCommentToServer(cmtData){
    try{
        const url = "/com_comment/insert";
		const config = {
			method: 'post',
			headers:{
				'content-Type': 'application/json; charset=utf-8'
			},
			body:JSON.stringify(cmtData)
		};
		const resp = await fetch(url, config); 
		const result = await resp.text(); 
		return result;
		
	}catch(error){
		console.log(error);
	}
}
  
document.getElementById('subBtn').addEventListener('click',()=>{
	const com_com_content = document.getElementById('com_com_content').value;
	
	if(com_com_content == null || com_com_content == ""){ 
		alert("댓글을 입력해주세요");
    document.getElementById('com_com_content').focus(); 
		return false;

	} else {
		let cmtData = { 
        com_com_content : com_com_content,
        com_num : com_num
    };
    console.log(">>> cmtData(댓글) : " + cmtData);
        
		insertCommentToServer(cmtData).then(result=>{
			if(result > 0){
				alert('댓글 작성 완료');
        		getCommentList(cmtData.com_num);
			}
		});
		
	}

})

 

2. Com_CommentController 작성

  1. com_comment.js에서 받아온 정보를 Com_CommentVO 객체 ccvo에 담고,
  2. ccvo에 현재 로그인 되어있는 id, nickname을 set한 뒤
  3. ccvo를 ccsv.insertCom_Comment(ccvo)로 보내기 (ccsv = Com_CommentService )
@Inject
	private Com_CommentService ccsv; 
	
//댓글 저장
@PostMapping(value="/insert", consumes="application/json", produces = {MediaType.TEXT_PLAIN_VALUE})
public ResponseEntity<String> post(@RequestBody Com_CommentVO ccvo, HttpServletRequest request){
		HttpSession ses = request.getSession();
		ccvo.setId("1111");
		ccvo.setNickname("{ses.nickname}");
		
		log.info(">>> ccvo : " + ccvo.toString());
		
		int isOk = ccsv.insertCom_Comment(ccvo);
		return isOk > 0? new ResponseEntity<String>("1",HttpStatus.OK)
				: new ResponseEntity<String>("0",HttpStatus.INTERNAL_SERVER_ERROR);
}

 

3. Com_CommentService 작성

package com.bewithme.www.service;

import java.util.List;

import com.bewithme.www.domain.Com_CommentVO;

public interface Com_CommentService {

	int insertCom_Comment(Com_CommentVO ccvo);

}

 

4. Com_CommentServiceImpl 작성

package com.bewithme.www.service;

import java.util.List;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.bewithme.www.domain.Com_CommentVO;
import com.bewithme.www.repository.Com_CommentDAO;

@Service
public class Com_CommentServiceImpl implements Com_CommentService{

	private static final Logger log = LoggerFactory.getLogger(Com_CommentServiceImpl.class);
	
	@Inject
	private Com_CommentDAO ccdao;
	
	@Override
	public int insertCom_Comment(Com_CommentVO ccvo) {
		//댓글 저장
		log.info("com_comment ServiceImpl insert in!");
		log.info("impl ccvo : "+ccvo);
		return ccdao.insert(ccvo);
	}

}

 

5. Com_CommentDAO작성

package com.bewithme.www.repository;

import com.bewithme.www.domain.Com_CommentVO;

public interface Com_CommentDAO {

	int insert(Com_CommentVO ccvo);

}

 

6. Com_CommentMapper 작성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bewithme.www.repository.Com_CommentDAO">

<insert id="insert">
  	insert into com_comment(id, com_num, com_com_content, nickname)
	values(#{id}, #{com_num}, #{com_com_content}, #{nickname})
</insert>

</mapper>