Spring 게시판 댓글 관련 기능 구현 - 댓글 작성, 수정, 삭제 (내 프로젝트에 적용)
Back-End/Spring 2019. 8. 21. 15:31댓글 작성, 댓글 삭제, 댓글 수정 기능 구현 (대댓글은 구현 안함)
memberboardview.jsp (게시글 상세보기) 중 일부
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <%@ include file="../include/header.jsp" %> <%@ include file="../include/menu.jsp" %> <script src="${path}/include/js/common.js"></script> <script src="${path}/ckeditor/ckeditor.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script> $(function(){ //댓글쓰기 버튼 (버튼을 눌러서 id값이 넘어와서 실행되는 자바스크립트 구문) listReply(); $("#btnReply").click(function(){ var r_content = $("#r_content").val(); //댓글의 내용 var member_bno = "${dto.member_bno}"; var params = {"r_content" : r_content, "member_bno" : member_bno}; $.ajax({ type: "post", //데이터를 보낼 방식 url: "reply_insert.do", //데이터를 보낼 url data: params, //보낼 데이터 success: function(data){//데이터를 보내는 것이 성공했을 시 출력되는 메시지 alert("댓글이 등록되었습니다."); listReply2(); } }); }); //댓글 목록을 출력하는 함수 function listReply(){ $.ajax({ type: "get", //get방식으로 자료를 전달 url: "reply_list.do?member_bno=${dto.member_bno}&curPage=${curPage}&search_option=${search_option}&keyword=${keyword}", //컨트롤러에 있는 list.do로 맵핑되고 게시글 번호도 같이 보낸다. success: function(result){ //자료를 보내는것이 성공했을때 출력되는 메시지 //댓글목록을 실행한 결과를 가져온다. $("#listReply").html(result); } }); } function listReply2(){ $.ajax({ type: "get", contentType: "application/json", url: "reply_list_json.do?member_bno=${dto.member_bno}", success: function(result){ console.log(result); var output="<table>"; for(var i in result){ var repl=result[i].replytext; repl = repl.replace(/ /gi," ");//공백처리 repl = repl.replace(/</gi,"<"); //태그문자 처리 repl = repl.replace(/>/gi,">"); repl = repl.replace(/\n/gi,"<br>"); //줄바꿈 처리 output += "<tr><td>"+result[i].name; date = changeDate(result[i].regdate); output += "("+date+")"; output += "<br>"+repl+"</td></tr>"; } output+="</table>"; $("#listReply").html(output); } }); } }); </script> //세션에 아이디가 저장되었을 경우 (로그인한 경우)에만 댓글 작성 창이 출력되도록 코드를 작성함 <c:if test = "${sessionScope.user_id != null or sessionScope.navername != null or sessionScope.kakaonickname != null or sessionScope.facebookname != null}"> <textarea rows = "5" cols = "80" id = "r_content" name = "r_content"></textarea> <br> <!-- 댓글쓰기 버튼을 클릭하면 위쪽에 있는 자바스크립트 구문이 실행되어서 컨트롤러로 맵핑됨 --><br><br> <button type = "button" id = "btnReply">댓글쓰기</button> </c:if> <!-- 댓글 목록 --> <!-- 댓글이 등록이 되면 listReply에 댓글이 쌓이게 된다. --> <div id = "listReply"></div> <body> </body> </html> | cs |
memberboardreply_list.jsp (댓글 수정, 삭제, 리스트를 출력하는 view)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <%@ include file="../include/header.jsp"%> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script> $(function(){ //댓글 수정 버튼 $("#btn_reply_Update").click(function(){ if(confirm("수정 하시겠습니까?")){ //수정하는데 필요한 정보들, 댓글 번호, 글 내용, 작성자 아이디, 게시글 번호를 변수에 저장한다. var rno = $("#rno").val(); var r_content = $("textarea#r_content").text(); var user_id = $("#user_id").val(); var member_bno = $("#member_bno").val(); //게시글 세부 페이지로 포워딩을 하기위해 페이지 관련 값들을 변수에 저장해서 컨트롤러로 보낸다. var curPage = $("#curPage").val(); var search_option = $("#search_option").val(); var keyword = $("#keyword").val(); //페이지 관련 값들과 댓글 수정에 필요한 값들을 url로 전송한다. document.form1.action="reply_update.do?rno="+rno+"&r_content="+encodeURI(r_content)+"&user_id="+user_id+"&member_bno="+member_bno+"&curPage="+curPage+"&search_option="+search_option+"&keyword="+keyword; document.form1.submit(); alert("댓글이 수정되었습니다.") } }); //댓글 삭제 버튼 $("#btn_reply_Delete").click(function(){ if(confirm("삭제 하시겠습니까?")){ //댓글 삭제를 하기위해 댓글 번호, 글 번호, 댓글 내용, 그리고 게시글 세부 페이지로 포워딩 하기 위해 페이지 관련 값들을 변수에 저장한다. var rno = $("#rno").val(); var member_bno = $("#member_bno").val(); var content = $("textarea#r_content").text(); var curPage = $("#curPage").val(); var search_option = $("#search_option").val(); var keyword = $("#keyword").val(); //url로 삭제에 필요한 변수들을 보낸다. document.form1.action="reply_delete.do?rno="+rno+"&member_bno="+member_bno+"&curPage="+curPage+"&search_option="+search_option+"&keyword="+keyword; document.form1.submit(); alert("댓글이 삭제되었습니다.") } }); }); </script> <body> <!-- 배열이 비어있지 않으면 참을 출력함. (다시말해서 배열에 값들이 있으면 댓글 리스트를 출력한다.) --> <c:if test = "${not empty map.list}"> <h2>댓글 리스트</h2> <table border = "1" width = "800px" align = "left"> <c:forEach var = "row" items = "${map.list}"> <tr> <td><br><br> 닉네임 : ${row.user_id} 작성일자 : ${row.reg_date} 댓글번호 : ${row.rno }<br><br><br> ${row.r_content} <!-- 폼태그 안에 위쪽에 있는 자바스크립트 구문에 필요한 값들을 노출시키지 않게 하기 위해 hidden타입으로 값들을 전달한다. --> <form method = "POST" id = "form1"> <input type = "hidden" id = "rno" name = "rno" value = "${row.rno}"> <input type = "hidden" id = "user_id" name = "user_id" value = "${row.user_id}"> <input type = "hidden" id = "member_bno" name = "member_bno" value = "${row.member_bno}"> <input type = "hidden" id = "curPage" name = "curPage" value = "${curPage}"> <input type = "hidden" id = "search_option" name = "search_option" value = "${search_option}"> <input type = "hidden" id = "keyword" name = "keyword" value = "${keyword}"> <div style = "width : 800px;"> <textarea id = "r_content" name = "r_content" rows = "3" cols = "80"></textarea></div><br><br> </form> <!-- 본인일 경우에만 댓글 수정버튼과 댓글 삭제 버튼이 출력되도록 설정함 --> <div style = "width:700px; text-align:right;"> <c:if test = "${sessionScope.user_id == row.user_id or sessionScope.navername == row.user_id or sessionScope.kakaonickname == row.user_id or sessionScope.facebookname == row.user_id}"> <button type = "button" id = "btn_reply_Update" >댓글 수정</button> <button type = "button" id = "btn_reply_Delete" >댓글 삭제</button> </c:if> </div> <br><br> </td> </tr> </c:forEach> </table> </c:if> </body> </html> | cs |
MemberBoardReplyController.java (게시판 댓글 관련 컨트롤러)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | package com.example.hansub_project.controller.board; import java.io.PrintWriter; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import com.example.hansub_project.model.board.dto.MemberBoardReplyDTO; import com.example.hansub_project.service.board.MemberBoardReplyService; //@ResponseBody를 붙이지 않아도 뷰가 아닌 데이터를 리턴할 수 있다 //하지만 @RestController을 사용할때 리턴값으로 바로 주소를 입력해버리면 그 주소 자체가 화면에 떠버리니 주의! @Controller public class MemberBoardReplyController { @Inject MemberBoardReplyService memberboardreplyService; //서비스를 호출하기 위해서 의존성을 주입함 //로깅을 위한 변수 private static final Logger logger= LoggerFactory.getLogger(MemberBoardReplyController.class); //댓글 리스트를 호출할때 맵핑되는 메소드 @RequestMapping("/board/reply_list.do") public ModelAndView list(int member_bno, ModelAndView mav, MemberBoardReplyDTO dto, @RequestParam(value="curPage")int curPage, @RequestParam(value="search_option") String search_option, @RequestParam(value="keyword") String keyword ) { List<MemberBoardReplyDTO> list = memberboardreplyService.list(member_bno); System.out.println("뷰에 전달할 데이터"+list); Map<String,Object> map = new HashMap<>(); //리스트의 값을 저장하기 위해 map객체를 생성하고 그 안에 리스트를 저장 map.put("list", list); System.out.println("뷰에 전달할 데이터"+map); mav.addObject("map", map); //뷰에 전달할 데이터 저장 mav.setViewName("board/memberboardreply_list"); //뷰의 이름 mav.addObject("curPage", curPage); mav.addObject("search_option", search_option); mav.addObject("keyword", keyword); return mav; } //댓글 목록을 ArrayList로 리턴함 @RequestMapping("/board/reply_list_json.do") public List<MemberBoardReplyDTO> list_json(int member_bno){ return memberboardreplyService.list(member_bno); } //댓글 생성 @RequestMapping("/board/reply_insert.do") //세부적인 url pattern public void insert (MemberBoardReplyDTO dto, HttpSession session, @RequestParam(value="r_content") String r_content, @RequestParam(value="member_bno") int member_bno) { //댓글 작성자 아이디 //현재 접속중인 사용자의 아이디 if (session.getAttribute("user_id") != null) { String user_id = (String)session.getAttribute("user_id"); dto.setUser_id(user_id); } //소셜로그인한 아이디도 받아와야 하기때문에 세션에 저장된 아이디값들을 추가함 if (session.getAttribute("navername") != null) { String user_id = (String)session.getAttribute("navername"); dto.setUser_id(user_id); } if (session.getAttribute("kakaonickname") != null) { String user_id = (String)session.getAttribute("kakaonickname"); dto.setUser_id(user_id); } if (session.getAttribute("facebookname") != null) { String user_id = (String)session.getAttribute("facebookname"); dto.setUser_id(user_id); } dto.setR_content(r_content); dto.setMember_bno(member_bno); //댓글이 테이블에 저장된다 memberboardreplyService.create(dto); } //댓글 수정 @RequestMapping("/board/reply_update.do") //세부적인 url pattern public String reply_update (@RequestParam(value="rno") int rno, @RequestParam(value="r_content") String r_content, @RequestParam(value="user_id") String user_id, @RequestParam(value="curPage")int curPage, @RequestParam(value="search_option")String search_option, @RequestParam(value="keyword")String keyword, @RequestParam(value="member_bno")int member_bno, MemberBoardReplyDTO dto) throws Exception{ dto.setRno(rno); dto.setR_content(r_content); dto.setUser_id(user_id); System.out.println("dto에 있는값들 출력함"+dto); memberboardreplyService.reply_update(dto); return "forward:/board/list.do"; } //댓글 삭제 @RequestMapping(value = "/board/reply_delete.do" , method = {RequestMethod.GET, RequestMethod.POST} ) //세부적인 url pattern public String reply_delete (@RequestParam(value="rno") int rno, MemberBoardReplyDTO dto, @RequestParam(value="member_bno") int member_bno, @RequestParam(value="curPage")int curPage, @RequestParam(value="search_option")String search_option, @RequestParam(value="keyword")String keyword) throws Exception{ //파라미터로 받는 값은 자동적으로 String타입으로 변환되기 때문에 int타입으로 변환해주어야 한다. memberboardreplyService.delete(rno); return "forward:/board/view.do"; } } | cs |
MemberBoardReplyService.java (댓글 관련 서비스 인터페이스)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.example.hansub_project.service.board; import java.util.List; import com.example.hansub_project.model.board.dto.MemberBoardReplyDTO; public interface MemberBoardReplyService { public List<MemberBoardReplyDTO> list(int member_bno); //댓글의 리스트 public void create(MemberBoardReplyDTO dto); //댓글 생성 public int count(int member_bno); //댓글 갯수 public void reply_update(MemberBoardReplyDTO dto); //댓글 수정 public void delete(int rno); //댓글을 삭제 } | cs |
MemberBoardReplyServiceImpl.java (댓글 관련 서비스 구현 클래스)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package com.example.hansub_project.service.board; import java.util.List; import javax.inject.Inject; import org.springframework.stereotype.Service; import com.example.hansub_project.model.board.dao.MemberBoardReplyDAO; import com.example.hansub_project.model.board.dto.MemberBoardReplyDTO; @Service //서비스 빈 생성 public class MemberBoardReplyServiceImpl implements MemberBoardReplyService { @Inject MemberBoardReplyDAO memberboardreplydao; //dao를 호출하기 위해 의존성을 주입 //댓글의 목록 @Override public List<MemberBoardReplyDTO> list(int member_bno) { return memberboardreplydao.list(member_bno); } //댓글 생성 @Override public void create(MemberBoardReplyDTO dto) { memberboardreplydao.create(dto); } //댓글 갯수 @Override public int count(int member_bno) { return 0; } //댓글 수정 @Override public void reply_update(MemberBoardReplyDTO dto) { memberboardreplydao.reply_update(dto); } //댓글 삭제 @Override public void delete(int rno) { memberboardreplydao.reply_delete(rno); } } | cs |
MemberBoardReplyDAO.java (게시판 댓글 관련 DAO 인터페이스)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.example.hansub_project.model.board.dao; import java.util.List; import com.example.hansub_project.model.board.dto.MemberBoardReplyDTO; public interface MemberBoardReplyDAO { public List<MemberBoardReplyDTO> list(int member_bno); //댓글의 목록 public int count(int member_bno); //댓글의 갯수 public void create(MemberBoardReplyDTO dto); //댓글의 작성 public void reply_update(MemberBoardReplyDTO dto); //댓글의 수정 public void reply_delete(int rno); //댓글의 삭제 } | cs |
MemberBoardReplyDAOImpl.java (게시판 댓글 관련 DAO 인터페이스 구현 클래스)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package com.example.hansub_project.model.board.dao; import java.util.List; import javax.inject.Inject; import org.apache.ibatis.session.SqlSession; import org.springframework.stereotype.Repository; import com.example.hansub_project.model.board.dto.MemberBoardReplyDTO; @Repository //dao 빈 설정 public class MemberBoardReplyDAOImpl implements MemberBoardReplyDAO { @Inject //의존관계를 주입함 SqlSession sqlSession; //댓글 목록 @Override public List<MemberBoardReplyDTO> list(int member_bno) { System.out.println(member_bno); return sqlSession.selectList("reply.listReply", member_bno); } //댓글의 갯수 @Override public int count(int member_bno) { return 0; } //댓글을 추가 @Override public void create(MemberBoardReplyDTO dto) { sqlSession.insert("reply.insertReply", dto); } //댓글의 수정 @Override public void reply_update(MemberBoardReplyDTO dto) { sqlSession.update("reply.updateReply", dto); } //댓글의 삭제 @Override public void reply_delete(int rno) { sqlSession.delete("reply.deleteReply", rno); } } | cs |
MemberBoardReplyDTO (게시판 댓글 관련 DTO 클래스)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package com.example.hansub_project.model.board.dto; import java.sql.Date; public class MemberBoardReplyDTO { private int rno; //댓글 번호 private int member_bno; //게시글의 번호 private String r_content; //댓글 내용 private String user_id; //댓글 작성자 id private Date reg_date; //java.util.Date, 작성일자 private Date join_date; //회원의 가입 일자 private int recommend; //추천수 public int getRno() { return rno; } public void setRno(int rno) { this.rno = rno; } public int getMember_bno() { return member_bno; } public void setMember_bno(int member_bno) { this.member_bno = member_bno; } public String getR_content() { return r_content; } public void setR_content(String r_content) { this.r_content = r_content; } public String getUser_id() { return user_id; } public void setUser_id(String user_id) { this.user_id = user_id; } public Date getReg_date() { return reg_date; } public void setReg_date(Date reg_date) { this.reg_date = reg_date; } public Date getJoin_date() { return join_date; } public void setJoin_date(Date join_date) { this.join_date = join_date; } public int getRecommend() { return recommend; } public void setRecommend(int recommend) { this.recommend = recommend; } @Override public String toString() { return "MemberBoardReplyDTO [rno=" + rno + ", member_bno=" + member_bno + ", r_content=" + r_content + ", user_id=" + user_id + ", reg_date=" + reg_date + ", join_date=" + join_date + ", recommend=" + recommend + "]"; } } | cs |
replyMapper.xml (댓글 관련 mapper.xml 파일)
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 --> <mapper namespace="reply"> <insert id = "insertReply"> <!-- 댓글을 추가 --> insert into member_reply (rno, member_bno, r_content, user_id) values (member_reply_bno.nextval, #{member_bno}, #{r_content}, #{user_id}) </insert> <select id = "listReply" resultType = "com.example.hansub_project.model.board.dto.MemberBoardReplyDTO"> <!-- 댓글의 작성자와 회원의 아이디가 같고, 글번호가 같을 경우에 댓글 리스트를 내림차순으로 검색함 --> select rno, r.member_bno, r.user_id, r.reg_date, r.r_content from member_reply r where r.member_bno = #{member_bno} order by rno </select> <update id = "updateReply"> <!-- 댓글의 번호와 회원의 아이디가 모두다 같을경우에만 수정할 수 있도록 쿼리를 설정 --> update member_reply set r_content = #{r_content} where rno = #{rno} </update> <delete id="deleteReply"> <!-- 댓글의 번호가 같을 경우에 삭제할 수 있도록 설정 (아이디는 앞에서 같지않으면 버튼조차 뜨지 않기때문에 따로 쿼리를 추가할 필요 없다.) --> delete from member_reply where rno = #{rno} </delete> </mapper> | cs |
'Back-End > Spring' 카테고리의 다른 글
스프링 에러 - url로 자료 전송시 발생 (HTTP Status 500 - The server encountered an unexpected condition that prevented it from fulfilling the request.)) (0) | 2019.08.21 |
---|---|
Spring 게시판 게시글 추천 기능 구현 (내 프로젝트에 적용) (2) | 2019.08.21 |
JSTL - 조건문 처리 (0) | 2019.08.16 |
ajax로 데이터 넘기기 (0) | 2019.08.14 |
Spring 게시판 게시글 쓰기(ckeditor 사용), 게시글 상세보기 (내 프로젝트에 적용) (0) | 2019.08.12 |