게시글 본문내용
|
|
다음검색
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 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | package board.database; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import common.TimeDiff; import conn.MysqlConn; public class BoardDAO { private final MysqlConn instance = MysqlConn.getInstance(); private final Connection conn = instance.getConn(); private PreparedStatement pstmt = null; private ResultSet rs = null; private BoardVO vo = null; private String sql = new String(""); //게시판 전체목록 페이징(총 레코드 건수) - 검색조건 public int boardListTotRecCnt(char kindYmd, int term, String searchConditionKey, String searchConditionValue) { int totRecCnt = 0; try { int prepareIdx = 0; boolean isExistSearchCondition = isExistSearchCondition(searchConditionKey, searchConditionValue); boolean isExistInterval = isExistInterval(kindYmd, term); sql = "select count(*) as totRecCnt from board "; if (isExistSearchCondition || isExistInterval) sql += "where "; String addPrepareSQL1 = searchConditionKey + " like ? "; if (isExistSearchCondition) sql += addPrepareSQL1; String addPrepareSQL2 = makeIntervalSQL(kindYmd, term, "wDate"); if (isExistSearchCondition && isExistInterval) { sql = sql + "and " + addPrepareSQL2; } else if (!isExistSearchCondition && isExistInterval) { sql += addPrepareSQL2; } pstmt = conn.prepareStatement(sql); if(isExistSearchCondition) pstmt.setString(++prepareIdx, "%" + searchConditionValue + "%"); if(isExistInterval) pstmt.setInt(++prepareIdx, term); rs = pstmt.executeQuery(); rs.next(); //ResultSet레코드움직이기(count함수는 무조건 0값조차 가져옴) totRecCnt = rs.getInt("totRecCnt"); } catch (SQLException e) { e.getMessage(); } finally { instance.rsClose(); instance.pstmtClose(); } return totRecCnt; } private boolean isExistSearchCondition(String searchConditionKey, String searchConditionValue) { boolean isExistSearchCondition = false; if (null != searchConditionKey && searchConditionKey.trim().length() > 0 && null != searchConditionValue && searchConditionValue.trim().length() > 0) isExistSearchCondition = true; return isExistSearchCondition; } private boolean isExistInterval(char kindYmd, int term) { boolean isExistInterval = false; if ((0 != kindYmd && ('Y' == kindYmd || 'M' == kindYmd || 'D' == kindYmd)) && 0 < term) isExistInterval = true; return isExistInterval; } //기간별 조회 SQL 조건문 추가 - Interval ex) interval 5 day, interval 1 Month private String makeIntervalSQL(char kindYmd, int term, String columnName) { String sqlInterval = null; if (isExistInterval(kindYmd, term)) { String sqlIntervalDate = new String("interval ? "); switch(kindYmd) { case 'Y' : sqlIntervalDate += "year"; break; case 'M' : sqlIntervalDate += "month"; break; case 'W' : sqlIntervalDate += "week"; break; case 'D' : sqlIntervalDate += "day"; break; default : break; } String sqlTerm = new String("date_sub(now(), " + sqlIntervalDate + ")"); sqlInterval = new String(sqlTerm + " <= " + columnName + " and " + columnName +" <= now() "); } else { sqlInterval = new String(""); } return sqlInterval; } //게시판 목록 조회-검색조건 //select *, (select count(*) from boardreply where boardIdx = board.idx) as replyCnt --이큐조인 //from board //where searchConditionKey like '%searchConditionValue%' --검색조건(제목,작성자,글내용) //and date_sub(now(), interval term kindYmd) <= wDate and wDate <= now() --기간별조회(daily, weekly, monthly, yearly) //order by idx desc limit startIndexNo, pageSize ; public List<BoardVO> searchBoardList(char kindYmd, int term, String searchConditionKey, String searchConditionValue, int startIndexNo, int pageSize) { List<BoardVO> vos = new ArrayList<>(); try { int prepareIdx = 0; boolean isExistSearchCondition = isExistSearchCondition(searchConditionKey, searchConditionValue); boolean isExistInterval = isExistInterval(kindYmd, term); sql = "select *, 0 as replyCnt from board "; if (isExistSearchCondition || isExistInterval) sql += "where "; String addPrepareSQL1 = searchConditionKey + " like ? "; if (isExistSearchCondition) sql += addPrepareSQL1; String addPrepareSQL2 = makeIntervalSQL(kindYmd, term, "wDate"); if (isExistSearchCondition && isExistInterval) { sql = sql + "and " + addPrepareSQL2; } else if (!isExistSearchCondition && isExistInterval) { sql += addPrepareSQL2; } sql += "order by idx desc limit ?, ?"; pstmt = conn.prepareStatement(sql); if (isExistSearchCondition) pstmt.setString(++prepareIdx, "%"+searchConditionValue+"%"); if (isExistInterval) pstmt.setInt(++prepareIdx, term); pstmt.setInt(++prepareIdx, startIndexNo); pstmt.setInt(++prepareIdx, pageSize); rs = pstmt.executeQuery(); while (rs.next()) { vo = new BoardVO(); vo.setIdx(rs.getInt("idx")); vo.setNickName(rs.getString("nickName")); vo.setTitle(rs.getString("title")); vo.setEmail(rs.getString("email")); vo.setHomepage(rs.getString("homepage")); vo.setContent(rs.getString("content")); vo.setStrWdate(rs.getString("wDate")); vo.setIntWDate(new TimeDiff().timeDiff(vo.getStrWdate()));//오늘날짜와 글쓴날짜의 시간차이 vo.setwDate(rs.getString("wDate")); vo.setReadNum(rs.getInt("readNum")); vo.setHostIp(rs.getString("hostIp")); vo.setRecommendNum(rs.getInt("recommendNum")); vo.setMid(rs.getString("mid")); vos.add(vo); } } catch (SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); instance.rsClose(); } return vos; } //게시글 조회 public BoardVO search(int idx) { try { sql = "SELECT " + " IDX, " + " NICKNAME, " + " TITLE, " + " EMAIL, " + " HOMEPAGE, " + " CONTENT, " + " WDATE, " + " READNUM, " + " HOSTIP, " + " RECOMMENDNUM, " + " MID " + "FROM " + " BOARD " + "WHERE" + " IDX = ?"; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, idx); rs = pstmt.executeQuery(); if (rs.next()) { vo = new BoardVO(); vo.setIdx(rs.getInt("idx")); vo.setNickName(rs.getString("nickName")); vo.setTitle(rs.getString("title")); vo.setEmail(rs.getString("email")); vo.setHomepage(rs.getString("homepage")); vo.setContent(rs.getString("content")); vo.setStrWdate(rs.getString("wDate")); vo.setIntWDate(new TimeDiff().timeDiff(vo.getStrWdate()));//오늘날짜와 글쓴날짜의 시간차이 vo.setwDate(rs.getString("wDate")); vo.setReadNum(rs.getInt("readNum")); vo.setHostIp(rs.getString("hostIp")); vo.setRecommendNum(rs.getInt("recommendNum")); vo.setMid(rs.getString("mid")); } } catch (SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); instance.rsClose(); } return vo; } //회원의 게시판에 올린 글 수 public int searchBoardWriteCnt(String mid, String nickname) { int cnt = 0; try { sql = "select count(mid) as count from board where mid = ? and nickName = ? "; pstmt = conn.prepareStatement(sql); pstmt.setString(1, mid); pstmt.setString(2, nickname); rs = pstmt.executeQuery(); rs.next(); //count()는 데이타가 없으면 '0'값을 취득하면서 rs도 같이 리턴하므로, 레코드를 읽는 목적으로 rs.next()사용 cnt = rs.getInt("count"); } catch (SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); instance.rsClose(); } return cnt; } //회원의 댓글에 올린 글 수 public int searchBoardreplyWriteCnt(String mid, String nickname) { int cnt = 0; try { sql = "select count(mid) as count from boardreply where mid = ? and nickName = ? "; pstmt = conn.prepareStatement(sql); pstmt.setString(1, mid); pstmt.setString(2, nickname); rs = pstmt.executeQuery(); rs.next(); //count()는 데이타가 없으면 '0'값을 취득하면서 rs도 같이 리턴하므로, 레코드를 읽는 목적으로 rs.next()사용 cnt = rs.getInt("count"); } catch (SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); instance.rsClose(); } return cnt; } //게시글 등록 public int insert(BoardVO vo) { int res = 0; try { sql = "insert into board values ( default, ?, ?, ?, ?, ?, default, ?, ?, default, default, default, default )"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, vo.getNickName()); pstmt.setString(2, vo.getTitle()); pstmt.setString(3, vo.getEmail()); pstmt.setString(4, vo.getHomepage()); pstmt.setString(5, vo.getContent()); pstmt.setString(6, vo.getMid()); pstmt.setString(7, vo.getHostIp()); res = pstmt.executeUpdate(); } catch(SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); } return res; } //게시글 조회수 1회 증가 public int updateReadNum(int idx) { int res = 0; try { sql = "update board set readNum = readNum + 1 where idx = ? "; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, idx); res = pstmt.executeUpdate(); } catch(SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); } return res; } //게시글 좋아요수 1회 증가 및 싫어요 1회 감소 public int updateRecommendNum(int idx) { int res = 0; try { sql = "update " + " board " + "set" + " recommendNum = recommendNum + 1 ," //좋아요 1회 증가 + " noRecommendNum = case noRecommendNum when 0 then 0 else noRecommendNum -1 end " //싫어요 1회 감소 + "where " + " idx = ? "; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, idx); res = pstmt.executeUpdate(); } catch(SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); } return res; } //게시글 싫어요수 1회 증가 및 좋아요 1회 감소 public int updateNoRecommendNum(int idx) { int res = 0; try { sql = "update " + " board " + "set" + " noRecommendNum = noRecommendNum + 1 ," //싫어요 1회 증가 + " recommendNum = case recommendNum when 0 then 0 else recommendNum -1 end " //좋아요 1회 감소 + "where " + " idx = ? "; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, idx); res = pstmt.executeUpdate(); } catch(SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); } return res; } //게시글 좋아요 총횟수 조회 public int searchBoardRecommendNum(int idx) { int recommendNum = -1; try { sql = "select recommendNum from board where idx = ? "; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, idx); rs = pstmt.executeQuery(); if(rs.next()) recommendNum = rs.getInt("recommendNum"); } catch (SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); instance.rsClose(); } return recommendNum; } //게시글 수정 public int update(BoardVO vo) { int res = 0; try { sql = "update board set title = ?, email = ?, homepage = ?, content = ?, hostIp = ? where idx = ? and mid = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, vo.getTitle()); pstmt.setString(2, vo.getEmail()); pstmt.setString(3, vo.getHomepage()); pstmt.setString(4, vo.getContent()); pstmt.setString(5, vo.getHostIp()); pstmt.setInt(6, vo.getIdx()); pstmt.setString(7, vo.getMid()); res = pstmt.executeUpdate(); } catch(SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); } return res; } //게시글 삭제 public int delete(int idx, String mid) { int res = 0; try { sql = "delete from board where idx = ? and mid = ? "; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, idx); pstmt.setString(2, mid); res = pstmt.executeUpdate(); } catch(SQLException e) { System.out.println("SQL 에러 : " + e.getMessage()); } finally { instance.pstmtClose(); } return res; } } | cs |
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 | package board; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import board.database.BoardDAO; import board.database.BoardVO; import common.Paging; public class BoardListCommand implements BoardInterface { @Override public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BoardDAO dao = new BoardDAO(); String searchCondition = request.getParameter("searchCondition"); String searchString = request.getParameter("searchString"); //페이징 설정하기 int pageNo = request.getParameter("pageNo")==null ? 1 : Integer.parseInt(request.getParameter("pageNo"));//현 페이지 int pageSize = request.getParameter("pageSize")==null ? 5 : Integer.parseInt(request.getParameter("pageSize"));//각 페이징할 목록의 레코드 갯수 int totalRecordSize = dao.boardListTotRecCnt((char)0, 0, searchCondition, searchString);//목록의 총 레코드 갯수 int blockingSize = request.getAttribute("blockSize")==null ? 3 : Integer.parseInt((String)request.getAttribute("blockSize"));//페이징할 블록 갯수 //페이징을 설정하면, 페이징 객체로 부터 산출된 페이징정보가 REQUEST 객체에 설정된다 Paging paging = new Paging(request, response); paging.setPaging(pageNo, totalRecordSize, pageSize, blockingSize); //한 페이징에 표시할 레코드 검색 List<BoardVO> vos = dao.searchBoardList((char)0, 0, searchCondition, searchString, paging.getStartIndexNo(), paging.getPageSize()); request.setAttribute("vos", vos); request.setAttribute("searchCondition", searchCondition); request.setAttribute("searchString", searchString); request.setAttribute("searchCount", totalRecordSize); } } | cs |
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 board; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import board.database.BoardDAO; import board.database.BoardReplyDAO; import board.database.BoardReplyVO; import board.database.BoardVO; import common.Paging; public class BoardDetailCommand implements BoardInterface { @Override public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String searchCondition = request.getParameter("searchCondition"); String searchString = request.getParameter("searchString"); int idx = Integer.parseInt(request.getParameter("idx"));//현재글idx BoardDAO dao = new BoardDAO(); //글 조회수 1회 증가 (조회수 중복방지처리 - 세션사용 : 'board+고유번호'를 객체배열에 추가 HttpSession session = request.getSession(); List<String> sBoardIdx = (List<String>) session.getAttribute("sBoardIdx"); if (null == sBoardIdx) { sBoardIdx = new ArrayList<>(); } String tmpBoardIdx = "board" + idx; if ( !sBoardIdx.contains(tmpBoardIdx) ) { dao.updateReadNum(idx);//글 조회수 1회 증가 DB저장 sBoardIdx.add(tmpBoardIdx); } session.setAttribute("sBoardIdx", sBoardIdx); int totRecCnt = dao.boardListTotRecCnt((char)0, 0, searchCondition, searchString); int preIdx = 0;//이전글idx int nextIdx = 0;//다음글idx if (0 < idx && 0 < totRecCnt && idx < totRecCnt) { if (1 >= idx) preIdx = 1; else preIdx = idx - 1; if (totRecCnt <= idx) nextIdx = totRecCnt; else nextIdx = idx + 1; } //게시글 가져오기 BoardVO vo = dao.search(idx); //이전글 소개 가져오기 BoardVO preVO = dao.search(preIdx); //다음글 소개 가져오기 BoardVO nextVO = dao.search(nextIdx); //댓글 가져오기 BoardReplyDAO replyDAO = new BoardReplyDAO(); List<BoardReplyVO> replyVOS = replyDAO.searchBoardReplyList(idx); request.setAttribute("vo", vo); request.setAttribute("preVO", preVO); request.setAttribute("nextVO", nextVO); request.setAttribute("replyVOS", replyVOS); request.setAttribute("searchCondition", searchCondition); request.setAttribute("searchString", searchString); } } | cs |
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 | package board; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @SuppressWarnings("serial") @WebServlet("*.bd") public class BoardController extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BoardInterface command = null; String viewPage = "/WEB-INF"; String uri = request.getRequestURI(); String com = uri.substring(uri.lastIndexOf("/")+1, uri.lastIndexOf(".")); //세션이 끊겼으면, 회원레벨을 비회원으로 바꿔서 작업의 진행을 로그인창으로 보낸다. HttpSession session = request.getSession(); int level = session.getAttribute("sLevel")==null ? 99 : (int) session.getAttribute("sLevel"); // if (4 < level) { // request.getRequestDispatcher("/").forward(request, response); // } // //게시판목록(검색키 조회) // else if (com.equals("boardList")) { command = new BoardListCommand(); command.execute(request, response); viewPage += "/board/boardList.jsp"; } //글쓰기 else if (com.equals("boardInput")) { command = new BoardInputCommand(); command.execute(request, response); viewPage += "/board/boardInput.jsp"; } //글쓰기OK else if (com.equals("boardInputOk")) { command = new BoardInputOkCommand(); command.execute(request, response); viewPage = "/message/message.jsp"; } //게시글 수정 else if (com.equals("boardUpdate")) { command = new BoardUpdateCommand(); command.execute(request, response); viewPage += "/board/boardUpdate.jsp"; } //게시글 수정Ok else if (com.equals("boardUpdateOk")) { command = new BoardUpdateOkCommand(); command.execute(request, response); viewPage = "/message/message.jsp"; } //게시글 삭제Ok else if (com.equals("boardDeleteOk")) { command = new BoardDeleteOkCommand(); command.execute(request, response); viewPage = "/message/message.jsp"; } //게시글 내용 조회 else if (com.equals("boardDetail")) { command = new BoardDetailCommand(); command.execute(request, response); viewPage += "/board/boardDetail.jsp"; } request.getRequestDispatcher(viewPage).forward(request, response); } } | cs |
AJax는 간단히 url매핑으로 적용했습니다
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 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <c:set var="ctxPath" value="${pageContext.request.contextPath}"/> <c:set var="newLine" value="\n" scope="page"/> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>boardDetail.jsp</title> <%@ include file="/include/bs4.jsp" %> <script> 'use strict'; function goBoardList() { boardForm.action = '${ctxPath}/boardList.bd'; boardForm.submit(); } function goPrevBoardDetail() { prevForm.submit(); } function goNextBoardDetail() { nextForm.submit(); } function checkBoardUpdate() { boardForm.action = '${ctxPath}/boardUpdate.bd'; boardForm.submit(); } function checkBoardDelete(){ boardForm.action = '${ctxPath}/boardDeleteOk.bd'; boardForm.submit(); } function viewReply(replyContent) { $("#replyContent").val(replyContent); } function checkReplyUpdate(replyIdx) { if (!confirm('댓글을 수정하겠습니까?')) return; let replyContent = $("#replyContent").val(); if("" == replyContent.trim()) { alert("댓글을 입력하세요"); $("#replyContent").focus(); return false; } let param = { idx : replyIdx, content : replyContent, hostIp : '${pageContext.request.remoteAddr}' }; $.ajax({ type: "post", url: "${ctxPath}/boardReplyUpdate",//간단히 URL패턴으로 했음 data: param, success: function(res) { if("1"==res) location.reload();//수정성공시 화면reload else alert('댓글이 수정되지 않았습니다'); }, error: function() { alert('요청 오류~~'); } }); } function checkReplyInput() { let replyContent = $("#replyContent").val(); if("" == replyContent.trim()) { alert("댓글을 입력하세요"); $("#replyContent").focus(); return false; } let param = { boardIdx : '${vo.idx}', content : replyContent, hostIp : '${pageContext.request.remoteAddr}' }; $.ajax({ type: "post", url: "${ctxPath}/boardReplyInput",//간단히 URL패턴으로 했음 data: param, success: function(res) { if('1'==res) location.reload();//등록성공시 화면reload else alert('댓글이 등록되지 않았습니다'); }, error: function() { alert('요청 오류~~'); } }); } function checkReplyDelete(replyIdx) { if (!confirm('댓글을 삭제하겠습니까?')) return; $.ajax({ type: "post", url: "${ctxPath}/boardReplyDelete",//간단히 URL패턴으로 했음 data: {idx : replyIdx}, success: function(res) { if("1"==res) location.reload();//삭제성공시 화면reload//전체화면 reload 많이 쓰면 화면깜박 생김 else alert('댓글이 삭제되지 않았습니다'); }, error: function() { alert('요청 오류~~'); } }); } function checkRecommend() { $.ajax({ type: "post", url: "${ctxPath}/boardRecommend",//간단히 URL패턴으로 했음 data: {idx : '${vo.idx}'}, success: function(recmmdNum) { if ("-1" == recmmdNum) { alert('좋아요가 처리되지 않았습니다'); } else { $("#recmmdNum").val(recmmdNum); location.reload();//'좋아요' 1회 증가 DB저장 성공시 화면 reload } }, error: function() { alert('요청 오류~~'); } }); } function checkNoRecommend() { $.ajax({ type: "post", url: "${ctxPath}/boardNoRecommend",//간단히 URL패턴으로 했음 data: { idx : '${vo.idx}' }, success: function(recmmdNum) { if ("-1" == recmmdNum) { alert('싫어요가 처리되지 않았습니다'); } else { $("#recmmdNum").val(recmmdNum); location.reload();////'싫어요' 1회 증가 DB저장 성공시 화면 reload } }, error: function() { alert('요청 오류~~'); } }); } </script> <style> th { background-color: #ddd; text-align: center; } </style> </head> <body> <c:if test="${0 < sLevel}" > <%@ include file="/include/header_home.jsp" %> <%@ include file="/include/nav.jsp" %> </c:if> <p><br></p> <div class="container"> <h2 class="text-center">글 내 용 보 기</h2> <br> <form name="boardForm" method="post"> <table class="table table-bordered"> <tr> <td colspan="4" class="text-right bt-0">IP : ${vo.hostIp}</td> </tr> <tr> <th>글쓴이</th> <td><c:out value="${vo.nickName}"/></td> <th>작성일</th> <td><c:out value="${fn:substring(vo.wDate, 0, 20)}"/> / <c:out value="${vo.intWDate}"/></td><!-- 2022.05.10 10:13:25 --> </tr> <tr> <th>이메일</th> <td><c:out value="${vo.email}"/></td> <th>조회수</th> <td><c:out value="${vo.readNum}"/></td> </tr> <tr> <th>홈페이지</th> <td><c:out value="${vo.homepage}"/></td> <th>좋아요</th> <td> ❤ ( <c:set var="recmmdNum" value="${vo.recommendNum}" scope="page"/><c:out value="${recmmdNum}"/> ) / <a href="xxxxjavascript:checkRecommend()"> 👍 </a> / <a href="xxxxjavascript:checkNoRecommend()"> 👎 </a> </td> </tr> <tr> <th>내용</th> <td colspan="3" height="200px"><c:out value="${fn:replace(vo.content, 'newLine', '<br>')}"/></td> </tr> <tr> <td colspan="4" class="text-center"> <input type="button" value="목록" xxxxonclick="goBoardList()" class="btn btn-secondary"/> <c:if test="${sMid==vo.mid}"> <input type="button" value="수정" xxxxonclick="checkBoardUpdate()" class="btn btn-secondary"/> <input type="button" value="삭제" xxxxonclick="checkBoardDelete()" class="btn btn-secondary"/> </c:if> </td> </tr> </table> <input type="hidden" name="idx" value="${vo.idx}" /> <input type="hidden" name="searchCondition" value="${searchCondition}" /> <input type="hidden" name="searchString" value="${searchString}" /> </form> <!-- 이전글/다음글 소개 시작 --> <form name="prevForm" method="post" action="${ctxPath}/boardDetail.bd"> <table> <tr> <td> <a href="xxxxjavascript:goPrevBoardDetail()">이전글 : ${preVO.title}</a><br> </td> </tr> </table> <input type="hidden" name="idx" value="${preVO.idx}" /> <input type="hidden" name="searchCondition" value="${searchCondition}" /> <input type="hidden" name="searchString" value="${searchString}" /> </form> <br> <form name="nextForm" method="post" action="${ctxPath}/boardDetail.bd"> <table> <tr> <td> <a href="xxxxjavascript:goNextBoardDetail()">다음글 : ${nextVO.title}</a><br> </td> </tr> </table> <input type="hidden" name="idx" value="${nextVO.idx}" /> <input type="hidden" name="searchCondition" value="${searchCondition}" /> <input type="hidden" name="searchString" value="${searchString}" /> </form> <!-- 이전글/다음글 소개 끝 --> <!-- 댓글(출력/입력) 시작 --> <!-- 댓글 출력 --> <table class="table table-hover text-center"> <tr> <th>작성자</th> <th>내용</th> <th>작성일</th> <th>접속IP</th> </tr> <c:forEach var="replyVO" items="${replyVOS}"> <tr> <td class="text-left"> ${replyVO.nickName} <c:if test="${sMid == replyVO.mid}"> <a href="xxxxjavascript:checkReplyUpdate('${replyVO.idx}')" class="btn btn-info btn-sm" ><font color="blue">✂</font></a> </c:if> <c:if test="${sMid == replyVO.mid || 0 == sLevel}"> <a href="xxxxjavascript:checkReplyDelete('${replyVO.idx}')" class="btn btn-info btn-sm" ><font color="red">❌</font></a> </c:if> </td> <td class="text-left"> <a href="xxxxjavascript:viewReply('${fn:replace(replyVO.content, 'newLine', '<br>')}')">${fn:replace(replyVO.content, 'newLine', '<br>')}</a> <c:if test="${replyVO.intWDate <= 24}"><font color="red"> new </font></c:if> </td> <td> <c:if test="${replyVO.intWDate <= 24}"><c:out value="${fn:substring(replyVO.wDate, 11, 19)}"/></c:if> <c:if test="${replyVO.intWDate > 24}"><c:out value="${fn:substring(replyVO.wDate, 0, 10)}"/></c:if> </td> <td>${replyVO.hostIp}</td> </tr> </c:forEach> </table> <!-- 댓글 입력(전체화면을 이동하지않고 비동기식 Ajax로 댓글form만 reload처리함--> <table class="table table-center"> <tr> <td style="width:85%"> <textarea rows="3" id="replyContent" name="replyContent" class="form-control"></textarea> </td> <td style="width:15%"> <p><input type="button" value="댓글등록" xxxxonclick="checkReplyInput()" class="btn btn-info btn-sm"/></p> <p>작성자 : ${sNickName}</p> <br> </td> </tr> </table> <!-- 댓글(출력/입력) 끝 --> </div> <c:if test="${0 < sLevel}" > <%@ include file="/include/footer.jsp" %> </c:if> </body> </html> | cs |
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 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <c:set var="ctxPath" value="${pageContext.request.contextPath}"/> <c:set var="sAdmin" value="${sAdmin}" scope="session" /> <c:set var="LF" value="\n" scope="page" /> <c:set var="BR" value="<br>" scope="page" /> <c:set var="First" value="<<" scope="page" /> <c:set var="Last" value=">>" scope="page" /> <c:set var="Prev" value="◁" scope="page" /> <c:set var="Next" value="▷" scope="page" /> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>boardList.jsp</title> <%@ include file="/include/bs4.jsp" %> <style></style> <script> 'use strict'; //검색기 처리 function checkSearching() { if ("" == $("#searchString").val()) { $("#searchString").focus(); } $("#pageNo").val(1); boardForm.action = "${ctxPath}/boardList.bd"; boardForm.submit(); } //게시글 상세조회 function goBoardDetail(idx, pageNo) { $("#idx").val(idx);//요청 파라미터 설정(게시판 목록에서 게시글 상세조회시 글번호로 조회 요청) $("#pageNo").val(pageNo); boardForm.action = "${ctxPath}/boardDetail.bd";//Post요청 boardForm.submit(); } function changePaging() { $("#pageNo").val(1); boardForm.action = "${ctxPath}/boardList.bd";//Post요청 boardForm.submit(); } function changePage(pageNo) { $("#pageNo").val(pageNo); boardForm.action = "${ctxPath}/boardList.bd";//Post요청 boardForm.submit(); } </script> </head> <body> <%@ include file="/include/header_home.jsp" %> <%@ include file="/include/nav.jsp" %> <p><br></p> <div class="container"> <h2 class="text-center">게 시 판 리 스 트</h2> <br> <form name="boardForm" method="post" action="${ctxPath}/boardList.bd"> <input type="hidden" id="pageNo" name="pageNo"/> <div class="row m-2"> <div class="col text-left"> <a href="${ctxPath}/boardInput.bd" class="btn btn-secondary">글쓰기</a> </div> <div class="col text-center"> <c:if test="${!empty searchString}"> (<font color="blue"> <c:choose> <c:when test="${'title'==searchCondition}"><c:out value="글제목" /></c:when> <c:when test="${'nickName'==searchCondition}"><c:out value="글쓴이" /></c:when> <c:when test="${'content'==searchCondition}"><c:out value="글내용" /></c:when> <c:otherwise><c:out value="" /></c:otherwise> </c:choose> </font>)(으)로 <font color="blue">${searchString}(을)를 검색한 결과</font> <font color="blue">${searchCount}건이 검색됬습니다</font> </c:if> </div> <!-- 페이징 처리 시작 --> <div class="col text-right"> <c:if test="${pageNo > 1}"> <a href="xxxxjavascript:changePage('1')" title='first'>${First}</a> <a href="xxxxjavascript:changePage('${pageNo - 1}')" title='prev'>${Prev}</a> </c:if> ${pageNo}Page / ${totPage}Pages <c:if test="${pageNo != totPage}"> <a href="xxxxjavascript:changePage('${pageNo + 1}')" title='next'>${Next}</a> </c:if> <c:if test="${pageNo != totPage}"> <a href="xxxxjavascript:changePage('${totPage}')" title='last'>${Last}</a> </c:if> </div> <!-- 페이징 처리 끝 --> <div class="text-right p-0"> <select name="pageSize" id="pageSize" xxxxonchange="changePaging()"> <option value="5" ${5==pageSize ? 'selected' : ''} >5건</option> <option value="10" ${10==pageSize ? 'selected' : ''} >10건</option> <option value="15" ${15==pageSize ? 'selected' : ''} >15건</option> <option value="20" ${20==pageSize ? 'selected' : ''} >20건</option> </select> </div> </div> <table class="table table-hover text-center"> <tr class="table-dark"> <th>글번호</th> <th class="text-left">글제목</th> <th>글쓴이</th> <th>글쓴날짜</th> <th>조회수</th> <th>추천수</th> </tr> <input type="hidden" id="idx" name="idx" /> <c:forEach var="vo" items="${vos}" > <tr> <td><c:out value="${curScrStartNo}"/></td> <td><a href="xxxxjavascript:goBoardDetail('${vo.idx}','${pageNo}')"><c:out value="${vo.title}"/></a> <c:if test="${vo.replyNum > 0}"><font color="blue">[<c:out value="${vo.replyNum}"/>]</font></c:if> <c:if test="${vo.intWDate <= 24}"><font color="red"> new </font></c:if> </td> <td><c:out value="${vo.nickName}"/></td> <td> <c:if test="${vo.intWDate <= 24}"><c:out value="${fn:substring(vo.wDate, 11, 19)}"/></c:if> <c:if test="${vo.intWDate > 24}"><c:out value="${fn:substring(vo.wDate, 0, 10)}"/></c:if> </td> <td><c:out value="${vo.readNum}"/></td> <td><c:out value="${vo.recommendNum}"/></td> </tr> <c:set var="curScrStartNo" value="${curScrStartNo-1}"/> </c:forEach> </table> <!-- 블럭페이징 처리 시작 --> <div class="text-center"> <div class="pagination justify-content-center"> <c:if test="${pageNo > 1}"> <li class="page-item"><a href='xxxxjavascript:changePage(1)' title='first' class="page-link text-secondary" >첫페이지</a></li> </c:if> <c:if test="${curBlock > 0}"> <li class="page-item"><a href="xxxxjavascript:changePage('${(curBlock-1)*blockSize+1}')" title='prevBlock' class="page-link text-secondary" >이전블록</a> </c:if> <c:forEach var="i" begin="${(curBlock*blockSize)+1}" end="${(curBlock*blockSize)+blockSize}"> <c:if test="${i <= totPage && i == pageNo}"> <li class="page-item active"><a href="xxxxjavascript:changePage('${i}')" class="page-link text-light bg-secondary border-secondary" >${i}</a> </c:if> <c:if test="${i <= totPage && i != pageNo}"> <li class="page-item"><a href="xxxxjavascript:changePage('${i}')" class="page-link text-secondary" >${i}</a> </c:if> </c:forEach> <c:if test="${curBlock < lastBlock}"> <li class="page-item"><a href="xxxxjavascript:changePage('${(curBlock+1)*blockSize+1}')" title='nextBlock' class="page-link text-secondary" >다음블록</a> </c:if> <c:if test="${pageNo != totPage}"> <li class="page-item"><a href="xxxxjavascript:changePage('${totPage}')" title='last' class="page-link text-secondary" >마지막페이지</a> </c:if> </div> </div> <!-- 블럭페이징 처리 끝 --> <br> <!-- 검색키 처리 시작 --> <div class="container text-center"> <select name="searchCondition" id="searchCondition" > <option value="title">글제목</option> <option value="nickName">글쓴이</option> <option value="content">글내용</option> </select> <input type="text" name="searchString" id="searchString"/> <input type="button" value="검색" xxxxonclick="checkSearching()"/> </div> <!-- 검색키 처리 끝 --> </form> </div> <br><br> <%@ include file="/include/footer.jsp" %> </body> </html> | cs |
소스는 Github에 올렸습니다. : https://github.com/kimwhitestar admin.adm / member.mbr / guest.gu / board.bd 레파지토리
2022/05/22 회원가입, 회원정보수정, 회원탈퇴 / 관리자 - 탈퇴회원목록조회 결과 사진 첨부
(회원관리의 등급 수정,삭제는 수정중)
회원가입 regex체크와 bs4 invalid-feedbak class 적용한 메세지 출력 Jsp 화일은
게시판 34번 글에 올렸습니다.

첫댓글 학습한 내용과 +a 들로 잘 채워진것 같습니다.
계속 멋진 모습 기대할께요. 수고하셨어요.