1. 개요
■ 지난 포스팅 : [JSP개발] 게시판 - 방명록 등록
방명록 등록 후 등록한 방명록이 보이도록 할 것이다. 방명록 방명록 목록은 방명록 등록 아래쪽에 나타나며, 한 번에 5개의 글이 보이도록 한다. 그리고 방명록이 5개가 넘을 경우 목록 하단에 페이지 번호가 보이게 할 것이다.
■ JSP
GuestbookForm.jsp : 방명록 목록을 보여주는 것과 페이지를 보여주는 부분을 추가한다.
Header.jsp : 상단 메뉴에서 방명록 클릭 시 GuestbookListAction이 실행되도록 수정한다.
■ Java
GuestbookListAction.java : 방명록 목록을 보여주는 Action이다. 방명록 목록을 가져오는것과 페이지를 생성하는것 2가지 작업을 처리한다.
GuestbookDAO.java : 방명록 목록과 방명록 개수를 가져오는 메서드를 추가한다.
GuestbookWriteAction.java : 방명록 등록 후 GuestbookListAction이 실행되도록 수정한다.
2. 소스 코드
■ GuestbookDAO.java
방명록 목록을 가져오는 getGuestbookList( ) 메서드에서는 계층 쿼리를 사용한다. 계층 쿼리는 지난번 답글 구현과 비슷하다.
방명록에서는 한 페이지당 총 5개의 방명록이 출력되게 한다. 그래서 페이지 번호에 +4한 값을 쿼리에 세팅한다.
페이지 처리를 하기 위해서는 방명록 개수가 필요하다. getGuestbookCount( ) 메서드는 DB에 등록된 총 방명록의 개수를 반납하는 기능을 한다.
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 | package jsp.guestbook.model; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import jsp.board.model.BoardBean; import jsp.common.util.DBConnection; public class GuestbookDAO { private Connection conn; private PreparedStatement pstmt; private ResultSet rs; private static GuestbookDAO instance; private GuestbookDAO(){} public static GuestbookDAO getInstance(){ if(instance==null) instance=new GuestbookDAO(); return instance; } // 시퀀스를 가져온다. public int getSeq() { int result = 1; try { conn = DBConnection.getConnection(); // 시퀀스 값을 가져온다. (DUAL : 시퀀스 값을 가져오기위한 임시 테이블) StringBuffer sql = new StringBuffer(); sql.append("SELECT guestbook_no_seq.NEXTVAL FROM DUAL"); pstmt = conn.prepareStatement(sql.toString()); rs = pstmt.executeQuery(); // 쿼리 실행 if (rs.next()) result = rs.getInt(1); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } close(); return result; } // end getSeq // 병명록 등록 public boolean guestbookInsert(GuestbookBean guestbook) { boolean result = false; try { conn = DBConnection.getConnection(); // 자동 커밋을 false로 한다. conn.setAutoCommit(false); StringBuffer sql = new StringBuffer(); sql.append("INSERT INTO GUESTBOOK"); sql.append(" (GUESTBOOK_NO, GUESTBOOK_ID, GUESTBOOK_PASSWORD, GUESTBOOK_CONTENT"); sql.append(" , GUESTBOOK_GROUP, GUESTBOOK_PARENT, GUESTBOOK_DATE)"); sql.append(" VALUES(?,?,?,?,?,?,sysdate)"); int no = guestbook.getGuestbook_no(); // 글번호(시퀀스 값) int group = guestbook.getGuestbook_group(); // 그룹번호 int parent = guestbook.getGuestbook_parent(); // 부모글번호 // 부모글일 경우 그룹번호와 글번호 동일 if(parent == 0) group = no; pstmt = conn.prepareStatement(sql.toString()); pstmt.setInt(1, no); pstmt.setString(2, guestbook.getGuestbook_id()); pstmt.setString(3, guestbook.getGuestbook_password()); pstmt.setString(4, guestbook.getGuestbook_content()); pstmt.setInt(5, group); pstmt.setInt(6, parent); int flag = pstmt.executeUpdate(); if(flag > 0){ result = true; conn.commit(); // 완료시 커밋 } } catch (Exception e) { try { conn.rollback(); // 오류시 롤백 } catch (SQLException sqle) { sqle.printStackTrace(); } e.printStackTrace(); throw new RuntimeException(e.getMessage()); } close(); return result; } // end boardInsert(); // 방명록 목록 보기 public ArrayList<GuestbookBean> getGuestbookList(int pageNum) { ArrayList<GuestbookBean> list = new ArrayList<GuestbookBean>(); try { conn = DBConnection.getConnection(); /* * SELECT * FROM * (SELECT ROWNUM AS rnum, * data.* * FROM * (SELECT LEVEL, * guestbook_no, * guestbook_id, * guestbook_password, * guestbook_content, * guestbook_group, * guestbook_parent, * guestbook_date, * FROM GUESTBOOK * START WITH guestbook_parent = 0 * CONNECT BY PRIOR guestbook_no = guestbook_parent * ORDER SIBLINGS BY guestbook_group desc) * data) * WHERE rnum>=? and rnum<=? ; */ StringBuffer sql = new StringBuffer(); sql.append("SELECT * FROM"); sql.append(" (SELECT ROWNUM AS rnum, data.* FROM "); sql.append(" (SELECT LEVEL, guestbook_no, guestbook_id,"); sql.append(" guestbook_password, guestbook_content,"); sql.append(" guestbook_group, guestbook_parent, guestbook_date"); sql.append(" FROM GUESTBOOK"); sql.append(" START WITH guestbook_parent = 0"); sql.append(" CONNECT BY PRIOR guestbook_no = guestbook_parent"); sql.append(" ORDER SIBLINGS BY guestbook_group desc)"); sql.append(" data) "); sql.append("WHERE rnum>=? and rnum<=?"); // 방명록 목록은 한 화면에 총 5개가 보이도록 한다. pstmt = conn.prepareStatement(sql.toString()); pstmt.setInt(1, pageNum); pstmt.setInt(2, pageNum+4); rs = pstmt.executeQuery(); while(rs.next()) { GuestbookBean guestbook = new GuestbookBean(); guestbook.setGuestbook_no(rs.getInt("guestbook_no")); guestbook.setGuestbook_id(rs.getString("guestbook_id")); guestbook.setGuestbook_password(rs.getString("guestbook_password")); guestbook.setGuestbook_content(rs.getString("guestbook_content")); guestbook.setGuestbook_group(rs.getInt("guestbook_group")); guestbook.setGuestbook_parent(rs.getInt("guestbook_parent")); guestbook.setGuestbook_date(rs.getDate("guestbook_date")); list.add(guestbook); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } close(); return list; } // 방명록의 개수를 가져온다. public int getGuestbookCount() { int result = 0; try { conn = DBConnection.getConnection(); StringBuffer sql = new StringBuffer(); sql.append("SELECT COUNT(*) FROM GUESTBOOK"); pstmt = conn.prepareStatement(sql.toString()); rs = pstmt.executeQuery(); if(rs.next()) result = rs.getInt(1); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } close(); return result; } // DB 자원해제 private void close() { try { if ( pstmt != null ){ pstmt.close(); pstmt=null; } if ( conn != null ){ conn.close(); conn=null; } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } // end close() } | cs |
■ GuestbookListAction.java
GuestbookListAction은 방명록 목록을 가져오고, 페이징 작업을 하는 Action이다.
GuestbookForm에서 페이지 파라미터를 가져온다. 만약 파라미터 값이 null이 아니라면 현재 페이지(spage)로 지정한다.
페이징 작업을 하기 위해 DAO에서 방명록의 개수를 가져온다.
가져온 방명록 개수로 전체 페이지 수를 계산한다. 여기서 현재 페이지가 전체 페이지보다 크다면 현재 페이지 번호를 강제로 전체 페이지 번호로 지정한다. (38번 줄)
이렇게 하는 이유는 아래와 같다.
만약 현재 페이지가 총 4개인데 주소창에서 위처럼 페이지 번호를 10을 입력한다. 당연히 10번째 페이지는 없으므로 화면에는 아무것도 출력되지 않는다. 이와 같은 경우를 막기 위해서 페이지 번호가 전체 페이지 번호보다 클 경우 페이지 번호를 전체 페이지 번호로 변경해준다.
시작과 끝 번호를 계산한다. 그리고 각각 페이지 변호들과 글 목록을 request 객체에 담는다.
다음 경로에 GuestbookForm.ge로 지정해 준다.
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 | package jsp.guestbook.action; import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jsp.common.action.Action; import jsp.common.action.ActionForward; import jsp.guestbook.model.GuestbookBean; import jsp.guestbook.model.GuestbookDAO; public class GuestbookListAction implements Action { @Override public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception { ActionForward forward = new ActionForward(); // 현재 페이지 번호 만들기 int spage = 1; String page = request.getParameter("page"); if(page != null) spage = Integer.parseInt(page); GuestbookDAO dao = GuestbookDAO.getInstance(); int listCount = dao.getGuestbookCount(); // 한 화면에 5개의 게시글을 보여지게함 // 페이지 번호는 총 5개, 이후로는 [다음]으로 표시 // 전체 페이지 수 int maxPage = (int)(listCount/5.0 + 0.9); // 만약 사용자가 주소창에서 페이지 번호를 maxPage 보다 높은 값을 입력시 // maxPage에 해당하는 목록을 보여준다. if(spage > maxPage) spage = maxPage; ArrayList<GuestbookBean> list = dao.getGuestbookList(spage*5-4); //시작 페이지 번호 int startPage = (int)(spage/5.0 + 0.8) * 5 - 4; //마지막 페이지 번호 int endPage = startPage + 4; if(endPage > maxPage) endPage = maxPage; // 4개 페이지번호 저장 request.setAttribute("spage", spage); request.setAttribute("maxPage", maxPage); request.setAttribute("startPage", startPage); request.setAttribute("endPage", endPage); // 방명록 목록 저장 request.setAttribute("list", list); // 단순 조회이므로 forward()사용 (= DB의 상태변화 없으므로) forward.setRedirect(false); forward.setNextPath("GuestbookForm.ge"); return forward; } } | cs |
■ GuestbookCommand.properties
프로퍼티에는 방명록 목록 명령어인 GuestbookListAction.ge를 추가한다.
1 2 3 4 5 6 | # Form Change GuestbookForm.ge=jsp.guestbook.action.GuestbookFormAction # Action GuestbookWriteAction.ge=jsp.guestbook.action.GuestbookWriteAction GuestbookListAction.ge=jsp.guestbook.action.GuestbookListAction | cs |
■ GuestbookForm.jsp
글 목록 부분의 <div id="listGuestForm"> 에 스크롤바가 생기도록 한다.
GuestbookListAction로부터 넘겨받은 방명록 목록을 화면에 출력한다. ArrayList 형태로 넘겨받았기 때문에 반복문인 <c:forEach> 태그를 이용하여 출력한다.
다음으로 페이지를 만드는 부분을 추가해 준다. 페이지가 5개를 넘어갈 경우 [이전]과 [다음]을 화면에 보여주도록 처리한다.
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 | <%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <title>방명록</title> <style type="text/css"> #wrap { width: 700px; margin: 0 auto 0 auto; } #comment{ text-align :left; } #listGuestForm{ text-align :center; overflow:scroll; overflow-x:hidden; height:220px; } #writeGuestForm, #pageForm{ text-align :center; } </style> <script type="text/javascript"> // 입력값 체크 function checkValue() { if(!document.guestbookInfo.guestbook_id.value){ alert("이름을 입력하세요."); return false; } if(!document.guestbookInfo.guestbook_password.value){ alert("비밀번호를 입력하세요."); return false; } if(!document.guestbookInfo.guestbook_content.value){ alert("내용을 입력하세요."); return false; } } </script> </head> <body> <br> <b><font size="5" color="gray">방명록</font></b> <hr size="1" width="700"> <br> <div id="wrap"> <!-- 글 등록 부분 시작--> <div id="writeGuestForm"> <form name="guestbookInfo" method="post" action="GuestbookWriteAction.ge" onsubmit="return checkValue()" > <table width="700"> <tr> <td>이름</td> <td><input type="text" name="guestbook_id"></td> <td>비밀번호</td> <td><input type="password" name="guestbook_password"></td> </tr> <tr><td colspan="4"> </td></tr> <tr> <td colspan="4"> <textarea rows="7" cols="80" name="guestbook_content"></textarea> </td> </tr> </table> <br> <input type="submit" value="등록"> </form> </div> <!-- 글 등록 부분 끝--> <!-- 글 목록 부분 시작 --> <div id="listGuestForm"> <form method="post" name=""> <!-- 방명록 내용 부분 --> <div id="comment"> <c:forEach var="guestbook" items="${requestScope.list}"> <hr size="1" width="700"> <label>${guestbook.guestbook_id}</label> <label>${guestbook.guestbook_date}</label> <a href="#">[답변]</a> <a href="#">[수정]</a> <a href="#">[삭제]</a><br> ${guestbook.guestbook_content} <br> </c:forEach> <hr size="1" width="700"> </div> <!-- 페이지 부분 --> <div id="pageForm"> <c:if test="${startPage != 1}"> <a href='GuestbookListAction.ge?page=${startPage-1}'>[ 이전 ]</a> </c:if> <c:forEach var="pageNum" begin="${startPage}" end="${endPage}"> <c:if test="${pageNum == spage}"> ${pageNum} </c:if> <c:if test="${pageNum != spage}"> <a href='GuestbookListAction.ge?page=${pageNum}'>${pageNum} </a> </c:if> </c:forEach> <c:if test="${endPage != maxPage }"> <a href='GuestbookListAction.ge?page=${endPage+1 }'>[다음]</a> </c:if> </div> </form> </div> <!-- 글 목록 부분 끝 --> </div> </body> </html> | cs |
■ GuestbookWriteAction.java
방명록 등록 Action이다.
GuestbookWriteAction 에서는 방명록 등록 후 방명록 목록이 보이도록 NextPath를 GuestbookListAction.ge로 지정한다.
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 | package jsp.guestbook.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jsp.common.action.Action; import jsp.common.action.ActionForward; import jsp.guestbook.model.GuestbookBean; import jsp.guestbook.model.GuestbookDAO; public class GuestbookWriteAction implements Action { @Override public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception { request.setCharacterEncoding("euc-kr"); // 인코딩 ActionForward forward = new ActionForward(); // 파리미터를 가져온다. String guestbook_id = request.getParameter("guestbook_id"); String guestbook_password = request.getParameter("guestbook_password"); String guestbook_content = request.getParameter("guestbook_content"); GuestbookDAO dao = GuestbookDAO.getInstance(); // 파라미터 값을 GuestbookBean에 세팅한다. GuestbookBean guestbook = new GuestbookBean(); guestbook.setGuestbook_no(dao.getSeq()); guestbook.setGuestbook_id(guestbook_id); guestbook.setGuestbook_password(guestbook_password); guestbook.setGuestbook_content(guestbook_content); boolean result = dao.guestbookInsert(guestbook); if(result){ forward.setRedirect(true); forward.setNextPath("GuestbookListAction.ge"); } return forward; } } | cs |
■ Header.jsp
상단 메뉴에서 방명록을 클릭 시 방명록 목록이 보여야 하므로 GuestbookListAction.ge를 이동 경로로 지정한다.
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 | <%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <title>상단 영역</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <style type="text/css"> #wrap{ text-align: center; width: 800px; height: 150px; } </style> <script type="text/javascript"> function changeView(value){ if(value == "0") // HOME 버튼 클릭시 첫화면으로 이동 { location.href="MainForm.do"; } else if(value == "1") // 로그인 버튼 클릭시 로그인 화면으로 이동 { location.href="LoginForm.do"; } else if(value == "2") // 회원가입 버튼 클릭시 회원가입 화면으로 이동 { location.href="JoinForm.do"; } else if(value == "3") // 로그아웃 버튼 클릭시 로그아웃 처리 { location.href="MemberLogoutAction.do"; } else if(value == "4") // 내정보 버튼 클릭시 회원정보 보여주는 화면으로 이동 { location.href="MemberInfoAction.do"; } else if(value == "5") { location.href="MemberListAction.do"; } else if(value == "6") { location.href="BoardListAction.bo"; } else if(value == "7") { location.href="GuestbookListAction.ge"; } } </script> </head> <body> <div id = "wrap"> <p> <button class="btn btn-success" onclick="changeView(0)">HOME</button> <!-- // 로그인 안되었을 경우 - 로그인, 회원가입 버튼을 보여준다. --> <c:if test="${sessionScope.sessionID==null}"> <button id="loginBtn" class="btn btn-primary" onclick="changeView(1)">로그인</button> <button id="joinBtn" class="btn btn-primary" onclick="changeView(2)">회원가입</button> </c:if> <!-- // 로그인 되었을 경우 - 로그아웃, 내정보 버튼을 보여준다. --> <c:if test="${sessionScope.sessionID!=null}"> <button id="logoutBtn" class="btn btn-primary" onclick="changeView(3)">로그아웃</button> <button id="updateBtn" class="btn btn-primary" onclick="changeView(4)">내정보</button> </c:if> <button id="joinBtn" class="btn btn-info" onclick="changeView(6)">게시판</button> <button id="joinBtn" class="btn btn-info" onclick="changeView(7)">방명록</button> <!-- 관리자 로그인 --> <c:if test="${sessionScope.sessionID !=null && sessionScope.sessionID=='admin'}"> <button id="memberViewBtn" class="btn btn-warning" onclick="changeView(5)">회원보기</button> </c:if> </p> </div> </body> </html> | cs |
3. 실행 결과
4. 소스코드 다운로드 (war 파일)
'코딩 > JSP' 카테고리의 다른 글
[JSP개발] 게시판 - 방명록 삭제 (0) | 2016.12.29 |
---|---|
[JSP개발] 게시판 - 방명록 답글 달기 (0) | 2016.12.28 |
[JSP개발] 게시판 - 방명록 등록 (0) | 2016.12.26 |
[JSP개발] 게시판 - 방명록 화면 (3) | 2016.12.25 |
[JSP개발] 게시판 - 글 수정 (3) | 2016.12.23 |