Spring - 게시판 만들기 연습 (Rest방식으로 댓글 수정, 삭제 구현하기)
1. 구현 화면
01) 댓글 상세보기 영역 생성
로그인한 회원 본인이 작성한 댓글에 수정 버튼이 보이도록 처리
수정 버튼을 클릭하면 댓글 아래의 빈공간에 댓글 상세보기 영역이 생성되도록 처리
닫기 버튼을 클릭하면 댓글 상세보기 영역이 사라지도록 처리
02) 댓글 수정처리
댓글 내용을 수정하고 수정버튼을 클릭하면 댓글 상세화면이 사라지고 수정처리가 된 댓글 목록 화면으로 전환
03) 댓글 삭제 처리
댓글 상세보기 영역의 삭제버튼 클릭하면 삭제알림 팝업을 띄우고 댓글 목록화면으로 전환
2. 소스코드
01) Controller(흐름제어)
ReplyController(댓글 관련 컨트롤러)
* 추가사항 110번 라인부터 시작
댓글 상세 정보 보기 Rest 맵핑처리
댓글 수정 처리 Rest 매핑처리
댓글 삭제 처리 Rest 매핑처리
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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | package com.example.spring02.controller.board; import java.util.List; import javax.inject.Inject; import javax.servlet.http.HttpSession; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; 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.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import com.example.spring02.model.board.dto.ReplyVO; import com.example.spring02.service.board.ReplyPager; import com.example.spring02.service.board.ReplyService; // REST : Representational State Transfer // 하나의 URI가 하나의 고유한 리소스를 대표하도록 설계된 개념 // http://localhost/spring02/list?bno=1 ==> url+파라미터 // http://localhost/spring02/list/1 ==> url // RestController은 스프링 4.0부터 지원 // @Controller, @RestController 차이점은 메서드가 종료되면 화면전환의 유무 //@Controller @RestController @RequestMapping("/reply/*") public class ReplyController { @Inject ReplyService replyService; // 1_1. 댓글 입력(@Controller방식으로 댓글 입력) @RequestMapping("insert.do") public void insert(@ModelAttribute ReplyVO vo, HttpSession session){ // 세션에 저장된 회원아이디를 댓글작성자에 세팅 String userId = (String) session.getAttribute("userId"); vo.setReplyer(userId); // 댓글 입력 메서드 호출 replyService.create(vo); } // 1_2. 댓글입력 (@RestController방식으로 json전달하여 댓글입력) // @ResponseEntity : 데이터 + http status code // @ResponseBody : 객체를 json으로 (json - String) // @RequestBody : json을 객체로 @RequestMapping(value="insertRest.do", method=RequestMethod.POST) public ResponseEntity<String> insertRest(@RequestBody ReplyVO vo, HttpSession session){ ResponseEntity<String> entity = null; try { // 세션에 저장된 회원아이디를 댓글작성자에 세팅 String userId = (String) session.getAttribute("userId"); vo.setReplyer(userId); // 댓글입력 메서드 호출 replyService.create(vo); // 댓글입력이 성공하면 성공메시지 저장 entity = new ResponseEntity<String>("success", HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); // 댓글입력이 실패하면 실패메시지 저장 entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST); } // 입력 처리 HTTP 상태 메시지 리턴 return entity; } // 2_1. 댓글 목록(@Controller방식 : veiw(화면)를 리턴) @RequestMapping("list.do") public ModelAndView list(@RequestParam int bno, @RequestParam(defaultValue="1") int curPage, ModelAndView mav, HttpSession session){ // 페이징 처리 int count = replyService.count(bno); // 댓글 갯수 ReplyPager replyPager = new ReplyPager(count, curPage); // 현재 페이지의 페이징 시작 번호 int start = replyPager.getPageBegin(); // 현재 페이지의 페이징 끝 번호 int end = replyPager.getPageEnd(); List<ReplyVO> list = replyService.list(bno, start, end, session); // 뷰이름 지정 mav.setViewName("board/replyList"); // 뷰에 전달할 데이터 지정 mav.addObject("list", list); mav.addObject("replyPager", replyPager); // replyList.jsp로 포워딩 return mav; } // 2_2. 댓글 목록(@RestController방식 : Json으로 데이터를 리턴) @RequestMapping("listJson.do") @ResponseBody // 리턴데이터를 json으로 변환(RestController사용시 @ResponseBody생략가능) public List<ReplyVO> listJson(@RequestParam int bno, @RequestParam(defaultValue="1") int curPage, HttpSession session){ // 페이징 처리 int count = replyService.count(bno); // 댓글 갯수 ReplyPager pager = new ReplyPager(count, curPage); // 현재 페이지의 페이징 시작 번호 int start = pager.getPageBegin(); // 현재 페이지의 페이징 끝 번호 int end = pager.getPageEnd(); List<ReplyVO> list = replyService.list(bno, start, end, session); // list를 리턴 return list; } // ** Controller 추가 사항 - Rest방식으로 댓글 목록, 수정, 삭제 처리 // 2_3. 댓글 목록(@RestController방식 : json으로 전달하여 목록생성) // /reply/list/1 => 1번 게시물의 댓글 목록 리턴 // /reply/list/2 => 2번 게시물의 댓글 목록 리턴 // @PathVariable : url에 입력될 변수값 지정 @RequestMapping(value="/list/{bno}/{curPage}", method=RequestMethod.GET) public ModelAndView replyList(@PathVariable("bno") int bno, @PathVariable int curPage, ModelAndView mav, HttpSession session){ // 페이징 처리 int count = replyService.count(bno); // 댓글 갯수 ReplyPager replyPager = new ReplyPager(count, curPage); // 현재 페이지의 페이징 시작 번호 int start = replyPager.getPageBegin(); // 현재 페이지의 페이징 끝 번호 int end = replyPager.getPageEnd(); List<ReplyVO> list = replyService.list(bno, start, end, session); // 뷰이름 지정 mav.setViewName("board/replyList"); // 뷰에 전달할 데이터 지정 mav.addObject("list", list); mav.addObject("replyPager", replyPager); // replyList.jsp로 포워딩 return mav; } // 3. 댓글 상세 보기 // /reply/detail/1 => 1번 댓글의 상세화면 리턴 // /reply/detail/2 => 2번 댓글의 상세화면 리턴 // @PathVariable : url에 입력될 변수값 지정 @RequestMapping(value="/detail/{rno}", method=RequestMethod.GET) public ModelAndView replyDetail(@PathVariable("rno") Integer rno, ModelAndView mav){ ReplyVO vo = replyService.detail(rno); // 뷰이름 지정 mav.setViewName("board/replyDetail"); // 뷰에 전달할 데이터 지정 mav.addObject("vo", vo); // replyDetail.jsp로 포워딩 return mav; } // 4. 댓글 수정 처리 - PUT:전체 수정, PATCH:일부수정 // RequestMethod를 여러 방식으로 설정할 경우 {}안에 작성 @RequestMapping(value="/update/{rno}", method={RequestMethod.PUT, RequestMethod.PATCH}) public ResponseEntity<String> replyUpdate(@PathVariable("rno") Integer rno, @RequestBody ReplyVO vo){ ResponseEntity<String> entity = null; try { vo.setRno(rno); replyService.update(vo); // 댓글 수정이 성공하면 성공 상태메시지 저장 entity = new ResponseEntity<String>("success", HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); // 댓글 수정이 실패하면 실패 상태메시지 저장 entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST); } // 수정 처리 HTTP 상태 메시지 리턴 return entity; } // 5. 댓글 삭제처리 @RequestMapping(value="/delete/{rno}") public ResponseEntity<String> replyDelete(@PathVariable("rno") Integer rno){ ResponseEntity<String> entity = null; try { replyService.delete(rno); // 댓글 삭제가 성공하면 성공 상태메시지 저장 entity = new ResponseEntity<String>("success", HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); // 댓글 삭제가 실패하면 실패 상태메시지 저장 entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST); } // 삭제 처리 HTTP 상태 메시지 리턴 return entity; } } | cs |
02) Service(비지니스 로직, DB연동 이외의 작업처리)
ReplyService(인터페이스)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.example.spring02.service.board; import java.util.List; import javax.servlet.http.HttpSession; import com.example.spring02.model.board.dto.ReplyVO; public interface ReplyService { // 1. 댓글 입력 public void create(ReplyVO vo); // 2. 댓글 목록 public List<ReplyVO> list(Integer bno, int start, int end, HttpSession session); // 3. 댓글 상세보기 public ReplyVO detail(Integer rno); // 4. 댓글 수정 public void update(ReplyVO vo); // 5. 댓글 삭제 public void delete(Integer rno); // 6. 댓글 갯수 public int count(Integer bno); } | cs |
ReplyServiceImpl(인터페이스 구현 클래스)
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 | package com.example.spring02.service.board; import java.util.List; import javax.inject.Inject; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Service; import com.example.spring02.model.board.dao.ReplyDAO; import com.example.spring02.model.board.dto.ReplyVO; @Service public class ReplyServiceImpl implements ReplyService { @Inject ReplyDAO replyDao; // 1. 댓글 입력 @Override public void create(ReplyVO vo) { replyDao.create(vo); } // 2. 댓글 목록 @Override public List<ReplyVO> list(Integer bno, int start, int end, HttpSession session) { List<ReplyVO> items = replyDao.list(bno, start, end); // 세션에서 현재 사용자 id값 저장 String userId = (String) session.getAttribute("userId"); for(ReplyVO vo : items){ // 댓글 목록중에 중에 비밀 댓글이 있을 경우 if(vo.getSecretReply().equals("y")){ if(userId== null){ // 비로그인 상태면 비밀 댓글로 처리 vo.setReplytext("비밀 댓글입니다."); } else { // 로그인 상태일 경우 String writer = vo.getWriter(); // 게시물 작성자 저장 String replyer = vo.getReplyer(); // 댓글 작성자 저장 // 로그인한 사용자가 게시물의 작성자X 댓글 작성자도 X 비밀댓글로 처리 if(!userId.equals(writer) && !userId.equals(replyer)) { vo.setReplytext("비밀 댓글입니다."); } } } } return items; } // 3. 댓글 상세보기 @Override public ReplyVO detail(Integer rno) { return replyDao.detail(rno); } // 4. 댓글 수정 @Override public void update(ReplyVO vo) { replyDao.update(vo); } // 5. 댓글 삭제 @Override public void delete(Integer rno) { replyDao.delete(rno); } // 6. 댓글 갯수 @Override public int count(Integer bno) { return replyDao.count(bno); } } | cs |
03) Model(DB연동 작업처리)
ReplyDAO(인터페이스)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.example.spring02.model.board.dao; import java.util.List; import com.example.spring02.model.board.dto.ReplyVO; public interface ReplyDAO { // 1. 댓글 입력 public void create(ReplyVO vo); // 2. 댓글 목록 public List<ReplyVO> list(Integer bno, int start, int end); // 3. 댓글 상세보기 public ReplyVO detail(Integer rno); // 4. 댓글 수정 public void update(ReplyVO vo); // 5. 댓글 삭제 public void delete(Integer rno); // 6. 댓글 갯수 public int count(Integer bno); } | cs |
ReplyDAOImpl(인터페이스 구현 클래스)
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 | package com.example.spring02.model.board.dao; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.apache.ibatis.session.SqlSession; import org.springframework.stereotype.Repository; import com.example.spring02.model.board.dto.ReplyVO; @Repository public class ReplyDAOImpl implements ReplyDAO { @Inject SqlSession sqlSession; // 1. 댓글 입력 @Override public void create(ReplyVO vo) { sqlSession.insert("reply.insertReply", vo); } // 2. 댓글 목록 @Override public List<ReplyVO> list(Integer bno, int start, int end) { Map<String, Object> map = new HashMap<String, Object>(); map.put("bno", bno); map.put("start", start); map.put("end", end); return sqlSession.selectList("reply.listReply", map); } // 3. 댓글 상세보기 @Override public ReplyVO detail(Integer rno) { return sqlSession.selectOne("reply.detailReply", rno); } // 4. 댓글 수정 @Override public void update(ReplyVO vo) { sqlSession.update("reply.updateReply", vo); } // 5. 댓글 삭제 @Override public void delete(Integer rno) { sqlSession.delete("reply.deleteReply", rno); } // 6. 댓글 갯수 @Override public int count(Integer bno) { return sqlSession.selectOne("reply.countReply", bno); } } | cs |
replyMapper.xml
댓글 상세보기(select 쿼리) - 32번 라인
댓글 수정처리(update 쿼리) - 38번 라인
댓글 삭제처리(delete 쿼리) - 45번 라인
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 | <?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"> <!-- 1. 댓글 입력 --> <insert id="insertReply"> INSERT INTO tbl_reply (rno, bno, replytext, replyer, secret_reply) VALUES (reply_seq.NEXTVAL, #{bno}, #{replytext}, #{replyer}, #{secretReply}) </insert> <!-- 2. 댓글 목록 --> <select id="listReply" resultType="com.example.spring02.model.board.dto.ReplyVO"> <include refid="pagingHeader"/> <!-- SELECT rno, bno, replytext, replyer, user_name AS userName, r.regdate, r.updatedate FROM tbl_reply r, tbl_member m WHERE r.replyer = m.user_id AND bno=#{bno} ORDER BY rno --> SELECT r.rno, bno, r.replytext, r.replyer, r.secret_reply AS secretReply, r.regdate, r.updatedate, m.user_name AS userName, (SELECT writer FROM tbl_board WHERE bno = r.bno) AS writer FROM tbl_reply r, tbl_member m WHERE r.replyer = m.user_id AND bno = #{bno} ORDER BY rno <include refid="pagingFooter"/> </select> <!-- 3. 댓글 상세보기 --> <select id="detailReply" resultType="com.example.spring02.model.board.dto.ReplyVO"> SELECT rno, bno, replytext, replyer, regdate, updatedate, secret_reply AS secretReply FROM tbl_reply WHERE rno = #{rno} </select> <!-- 4. 댓글 수정 --> <select id="updateReply"> UPDATE tbl_reply SET replytext = #{replytext} WHERE rno = #{rno} </select> <!-- 5. 댓글 삭제 --> <delete id="deleteReply"> DELETE FROM tbl_reply WHERE rno = #{rno} </delete> <!-- 6 .댓글 갯수(for 페이징처리) --> <select id="countReply" resultType="int"> SELECT COUNT(*) FROM tbl_reply WHERE bno=#{bno} </select> <!-- 페이징 sql --> <sql id="pagingHeader"> SELECT * FROM ( SELECT ROWNUM AS rn, A.* FROM ( </sql> <sql id="pagingFooter"> ) A ) WHERE rn BETWEEN #{start} AND #{end} </sql> </mapper> | cs |
04) View(화면)
view.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 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>게시글 작성</title> <%@ include file="../include/header.jsp" %> <script> $(document).ready(function(){ /* 게시글 관련 */ // 1. 게시글 수정 $("#btnUpdete").click(function(){ /* var title = document.form1.title.value; ==> name속성으로 처리할 경우 var content = document.form1.content.value; var writer = document.form1.writer.value; */ var title = $("#title").val(); var content = $("#content").val(); //var writer = $("#writer").val(); if(title == ""){ alert("제목을 입력하세요"); document.form1.title.focus(); return; } if(content == ""){ alert("내용을 입력하세요"); document.form1.content.focus(); return; } /* if(writer == ""){ alert("이름을 입력하세요"); document.form1.writer.focus(); return; } */ document.form1.action="${path}/board/update.do" // 폼에 입력한 데이터를 서버로 전송 document.form1.submit(); }); // 2. 게시글 삭제 $("#btnDelete").click(function(){ if(confirm("삭제하시겠습니까?")){ document.form1.action = "${path}/board/delete.do"; document.form1.submit(); } }); // 3. 게시글 목록으로 이동 - 버튼 클릭시 상세보기화면에 있던 페이지, 검색옵션, 키워드 값을 가지로 목록으로 이동 $("#btnList").click(function(){ location.href="${path}/board/list.do?curPage=${curPage}&searchOption=${searchOption}&keyword=${keyword}"; }); /* 댓글 관련 */ // 1. 댓글 입력 $("#btnReply").click(function(){ //reply(); // 폼데이터 형식으로 입력 replyJson(); // json 형식으로 입력 }); // 2. 댓글 목록 //listReply("1"); // 댓글 목록 불러오기 //listReply2(); // json 리턴방식 listReplyRest("1"); // rest방식 }); // 1_1. 댓글 입력 함수(폼 데이터 방식) function reply(){ var replytext=$("#replytext").val(); var bno="${dto.bno}" // 비밀댓글 체크여부 var secretReply = "n"; // 태그.is(":속성") 체크여부 true/false if( $("#secretReply").is(":checked") ){ secretReply = "y"; } // 비밀댓글 파라미터 추가 var param="replytext="+replytext+"&bno="+bno+"&secretReply="+secretReply; $.ajax({ type: "post", url: "${path}/reply/insert.do", data: param, success: function(){ alert("댓글이 등록되었습니다."); //listReply2(); listReply("1"); } }); } // 1_2. 댓글 입력 함수(json방식) function replyJson(){ var replytext=$("#replytext").val(); var bno="${dto.bno}" // 비밀댓글 체크여부 var secretReply = "n"; // 태그.is(":속성") 체크여부 true/false if( $("#secretReply").is(":checked") ){ secretReply = "y"; } $.ajax({ type: "post", url: "${path}/reply/insertRest.do", headers: { "Content-Type" : "application/json" }, dateType: "text", // param형식보다 간편 data: JSON.stringify({ bno : bno, replytext : replytext, secretReply : secretReply }), success: function(){ alert("댓글이 등록되었습니다."); // 댓글 입력 완료후 댓글 목록 불러오기 함수 호출 //listReply("1"); // 전통적인 Controller방식 //listReply2(); // json리턴 방식 listReplyRest("1"); // Rest 방식 } }); } // 2_1. 댓글 목록 - 전통적인 Controller방식 function listReply(num){ $.ajax({ type: "get", url: "${path}/reply/list.do?bno=${dto.bno}&curPage="+num, success: function(result){ // responseText가 result에 저장됨. $("#listReply").html(result); } }); } // 2_2. 댓글 목록 - RestController를 이용 json형식으로 리턴 function listReply2(){ $.ajax({ type: "get", //contentType: "application/json", ==> 생략가능(RestController이기때문에 가능) url: "${path}/reply/listJson.do?bno=${dto.bno}", success: function(result){ console.log(result); var output = "<table>"; for(var i in result){ output += "<tr>"; output += "<td>"+result[i].userName; output += "("+changeDate(result[i].regdate)+")<br>"; output += result[i].replytext+"</td>"; output += "<tr>"; } output += "</table>"; $("#listReply").html(output); } }); } // 2_2. 댓글 목록 - 날짜 형식 변환 함수 작성 function changeDate(date){ date = new Date(parseInt(date)); year = date.getFullYear(); month = date.getMonth(); day = date.getDate(); hour = date.getHours(); minute = date.getMinutes(); second = date.getSeconds(); strDate = year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second; return strDate; } // 2_3. 댓글 목록 - Rest방식 function listReplyRest(num){ $.ajax({ type: "get", url: "${path}/reply/list/${dto.bno}/"+num, success: function(result){ // responseText가 result에 저장됨. $("#listReply").html(result); } }); } // **댓글 수정화면 생성 함수 function showReplyModify(rno){ $.ajax({ type: "get", url: "${path}/reply/detail/"+rno, success: function(result){ $("#modifyReply").html(result); // 태그.css("속성", "값") $("#modifyReply").css("visibility", "visible"); } }) } </script> <style> #modifyReply { width: 600px; height: 130px; background-color: gray; padding: 10px; z-index: 10; visibility: hidden; } </style> </head> <body> <%@ include file="../include/menu.jsp" %> <h2>게시글 보기</h2> <form name="form1" method="post"> <div> <!-- 원하는 날짜형식으로 출력하기 위해 fmt태그 사용 --> 작성일자 : <fmt:formatDate value="${dto.regdate}" pattern="yyyy-MM-dd a HH:mm:ss"/> <!-- 날짜 형식 => yyyy 4자리연도, MM 월, dd 일, a 오전/오후, HH 24시간제, hh 12시간제, mm 분, ss 초 --> </div> <div> 조회수 : ${dto.viewcnt} </div> <div> 제목 <input name="title" id="title" size="80" value="${dto.title}" placeholder="제목을 입력해주세요"> </div> <div> 내용 <textarea name="content" id="content" rows="4" cols="80" placeholder="내용을 입력해주세요">${dto.content}</textarea> </div> <div> 이름 <%-- <input name="writer" id="writer" value="${dto.writer}" placeholder="이름을 입력해주세요"> --%> ${dto.userName} </div> <div style="width:650px; text-align: center;"> <!-- 게시물번호를 hidden으로 처리 --> <input type="hidden" name="bno" value="${dto.bno}"> <!-- 본인이 쓴 게시물만 수정, 삭제가 가능하도록 처리 --> <c:if test="${sessionScope.userId == dto.writer}"> <button type="button" id="btnUpdete">수정</button> <button type="button" id="btnDelete">삭제</button> </c:if> <!-- 상세보기 화면에서 게시글 목록화면으로 이동 --> <button type="button" id="btnList">목록</button> </div> </form> <div style="width:650px; text-align: center;"> <br> <!-- 로그인 한 회원에게만 댓글 작성폼이 보이게 처리 --> <c:if test="${sessionScope.userId != null}"> <textarea rows="5" cols="80" id="replytext" placeholder="댓글을 작성해주세요"></textarea> <br> <!-- 비밀댓글 체크박스 --> <input type="checkbox" id="secretReply">비밀 댓글 <button type="button" id="btnReply">댓글 작성</button> </c:if> </div> <!-- 댓글 목록 출력할 위치 --> <div id="listReply"></div> </body> </html> | cs |
replyList.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 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <%@ include file="../include/header.jsp" %> </head> <body> <table style="width:700px"> <!-- 댓글 목록 --> <c:forEach var="row" items="${list}"> <tr> <td> ${row.userName}(<fmt:formatDate value="${row.regdate}" pattern="yyyy-MM-dd HH:mm:ss"/>) <br> ${row.replytext} <br> <!-- 본인 댓글만 수정버튼 생성되도록 처리 --> <c:if test="${sessionScope.userId == row.replyer}"> <input type="button" id="btnModify" value="수정" onclick="showReplyModify('${row.rno}')"> </c:if> <hr> </td> </tr> </c:forEach> <!-- 페이징 --> <tr style="text-align: center;"> <td> <!-- 현재 페이지 블럭이 1보다 크면 처음페이지로 이동 --> <c:if test="${replyPager.curBlock > 1}"> <a href="javascript:listReply('1')">[처음]</a> </c:if> <!-- 현재 페이지 블럭이 1보다 크면 이전 페이지 블럭으로 이동 --> <c:if test="${replyPager.curBlock > 1}"> <a href="javascript:listReply('${replyPager.prevPage}')">[이전]</a> </c:if> <!-- 페이지 블럭 처음부터 마지막 블럭까지 --> <c:forEach var="num" begin="${replyPager.blockBegin}" end="${replyPager.blockEnd}"> <c:choose> <c:when test="${num == replyPager.curPage}"> ${num} </c:when> <c:otherwise> <a href="javascript:listReply('${num}')">${num}</a> </c:otherwise> </c:choose> </c:forEach> <!-- 현재 페이지 블럭이 전체 페이지 블럭보다 작거나 같으면 다음페이지로 이동 --> <c:if test="${replyPager.curBlock <= replyPager.totBlock}"> <a href="javascript:listReply('${replyPager.nextPage}')">[다음]</a> </c:if> <!-- 현재 페이지 블럭이 전체 페이지 블럭보다 작거나 같으면 끝으로 이동 --> <c:if test="${replyPager.curBlock <= replyPager.totBlock}"> <a href="javascript:listReply('${replyPager.totPage}')">[끝]</a> </c:if> </td> </tr> </table> <!-- 댓글 수정 영역--> <div id="modifyReply"></div> </body> </html> | cs |
replyDetail.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 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <%@ include file="../include/header.jsp" %> <script> //3. 댓글 수정 $("#btnReplyUpdate").click(function(){ var detailReplytext = $("#detailReplytext").val(); $.ajax({ type: "put", url: "${path}/reply/update/${vo.rno}", // 기본값 text/html을 json으로 변경 headers: { "Content-Type":"application/json" }, // 데이터를 json형태로 변환 data: JSON.stringify({ replytext : detailReplytext }), dataType: "text", success: function(result){ if(result == "success"){ $("#modifyReply").css("visibility", "hidden"); // 댓글 목록 갱신 listReplyRest("1"); } } }); }); // 4. 댓글 상세화면 닫기 $("#btnReplyClose").click(function(){ $("#modifyReply").css("visibility", "hidden"); }); // 5. 댓글 삭제 $("#btnReplyDelete").click(function(){ if(confirm("삭제하시겠습니까?")){ $.ajax({ type: "delete", url: "${path}/reply/delete/${vo.rno}", success: function(result){ if(result == "success"){ alert("삭제되었습니다."); $("#modifyReply").css("visibility", "hidden"); listReplyRest("1"); } } }); } }); </script> </head> <body> 댓글 번호 : ${vo.rno}<br> <textarea id="detailReplytext" rows="5" cols="82">${vo.replytext}</textarea> <div style="text-align: center;"> <!-- 본인 댓글만 수정, 삭제가 가능하도록 처리 --> <c:if test="${sessionScope.userId == vo.replyer}"> <button type="button" id="btnReplyUpdate" >수정</button> <button type="button" id="btnReplyDelete" >삭제</button> </c:if> <button type="button" id="btnReplyClose" >닫기</button> </div> </body> </html> | cs |