'방명록'에 해당되는 글 1건

  1. 2017.03.08 게시판 관리기능 - 여러 개의 게시판이 필요할 때 (4/5)

글을 작성하면서 구현을 하다가 (1/), (2/), (3/)까지는 이어졌는데, 갑자기 구현에  신경을 쓰느라 이번 글에서는 어느 정도 완성된 버전에서 다시 기술한다.

맥은 어느 정도 유지가 되지만, 이전 글에서 스무드하게 이어지지 못해  이해에 어려움이 있을 수도 있을 것 같다.

1. 게시판 관리 기능 중 "게시판 목록 보기"

Header의 메뉴 창에서 "관리자" 메뉴를 선택하면 "게시판 목록 보기" 창으로 이동하게 된다.  url은 "localhost:8080/board/manager/list" 이다. 즉, 게시판 목록 보기 기능을 구현한 것이다.

1.1 BoardController에서 url /manager/list를 처리

  @RequestMapping(value="/list", method=RequestMethod.GET)

  public void list(Criteria cri, Model model) throws Exception {    // View로는 기본적으로 list.jsp가 사용됨

    List<BoardVO> list = service.list(cri);    // 게시판 목록정보를 가져 온다.

    for(int i = 0;i < list.size();i++) {           // 게시판의 게시글 수를 가져와 저장한다.

     BoardVO board = list.get(i);

board.setNofArticle(aService.listCount());    //

    }

    model.addAttribute("list", list);         // 게시판 목록 정보를 model에 저장한다.

    PageMaker pm = new PageMaker();     // 페이징 처리를 위해 필요한 정보를 담을 클래스를 인스턴스화

    pm.setCri(cri);                                  // 페이징 처리를 위한 기준을 저장 (cri는 기본값이 있지만, 사용

    pm.setTotalCount(service.listCount());    // 자가 파라미터로 제공 가능. 전체 게시판의 수를 얻는다.

    model.addAttribute("pageMaker", pm); // 페이징 정보를 model에 저장

  }                                                     // view는 기본적으로 list.jsp

1.2 list.jsp : "게시판 목록 보기" view

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>게시판 목록 보기</title>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/common.css"/>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/boardlist.css"/>

</head>

<body>

<header> <!-- 헤더 영역 정의 -->

  <jsp:include page="../common/header.jsp" flush="false"/>

</header>

<section id="wrap"> <!-- 본문 영역 정의 -->

  <section id="lnav"> <!-- 사이드 메뉴 영역 정의 -->

    <jsp:include page="../common/lnav.jsp" flush="false"/>

  </section>

  <section id="content"> <!-- 내용 영역 정의 -->

    <h1>게시판 목록 보기</h1>

    <table border="1">

      <c:if test="${pageMaker.totalCount > 0}">

<tr>

  <td colspan="6">

    ${pageMaker.cri.pageStart}-${pageMaker.cri.pageEnd}

    [${pageMaker.cri.page}/${pageMaker.totalPageCount}]

  </td>

</tr>

      </c:if>


      <c:choose>

<c:when test="${list.size() == 0}">

  <tr>

    <td colspan="6">

      게시판이 없습니다.

    </td>

  </tr>

</c:when>

<c:otherwise>

  <tr>

    <td style="text-align: center" width="6%">번호</td>

    <td style="text-align: center" width="21%">게시판 이름</td>

    <td style="text-align: center" width="13%">게시판 유형</td>

    <td style="text-align: center" width="32%">URL</td>

    <td style="text-align: center" width="17%">생성일</td>

    <td style="text-align: center" width="11%">게시글 수</td>

  </tr>

  <c:forEach var="board" items="${list}">

    <tr>

      <td>${board.board_id}</td>

      <td>

<c:set var="query" value="board_id=${board.board_id}&page=${pageMaker.cri.page}

 &perPageNum=${pageMaker.cri.perPageNum}"/>

<a href="<c:url value="manager/read?${query}"/>">${board.board_name}</a>

      </td>

      <td>${board.board_type}</td>

      <td>${board.url}</td>

      <td><fmt:formatDate value="${board.creating_date}" pattern="yyyy-MM-dd" /></td>

      <td>${board.nofArticle}</td>

    </tr>

  </c:forEach>

  <tr>

    <td colspan="6">

      <c:if test="${pageMaker.prev == true}">

<a href="<c:url value="/manager/list?page=${pageMaker.startPage-1}&perPageNum=

${pageMaker.cri.perPageNum}"/>">이전</a>

      </c:if>

      <c:forEach var="pno" begin="${pageMaker.startPage}" end="${pageMaker.endPage}">

<a href="<c:url value="/manager/list?page=${pno}&perPageNum=

${pageMaker.cri.perPageNum}" />">[${pno}]</a>

      </c:forEach>

      <c:if test="${pageMaker.next == true}">

<a href="<c:url value="/manager/list?page=${pageMaker.endPage+1}

&perPageNum=${pageMaker.cri.perPageNum}"/>">다음</a>

      </c:if>

    </td>

  </tr>

</c:otherwise>

      </c:choose>

      <tr>

        <td colspan="6">

  <a href="write">게시판 만들기</a>

        </td>

      </tr>

    </table>

  </section>

</section>

<footer> <!-- 풋터 영역 정의 -->

<jsp:include page="../common/footer.jsp" flush="false"/>

</footer>

</body>

</html>


아래의 그림과 같은 내용이 보여진다. (물론 처음에는 아무것도 없겠지만... 지금은 게시판 1개를 추가한 것)


1.3 boardlist.css : 위 그림과 같은 테이블 형태의 게시판 목록을 보여주도록 꾸며주는 파일

@CHARSET "UTF-8";

#content table {

width: 100%;

border: 1px solid black;

border-collapse: collapse;

border-spacing: 0px;

margin-top: 20px;

}

#content td {

border: 1px solid black;

border-collapse: collapse;

border-spacing: 0px;

padding: 5px;

}


2. 게시판 생성 : "게시판 만들기" 메뉴 동작

2.1 BoardController /manager/write 동작

  위 list.jsp 파일에서 "게시판 만들기" 버튼을 누르면 BoardController로 /manager/list가 전달된다.

 @RequestMapping(value="/write", method=RequestMethod.GET)

  public String write() {

    return "/manager/writeForm";    // writeForm.jsp를 보여준다.

  }


2.2 writeForm.jsp : 게시판 추가를 위한 Form 입력

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>게시판 만들기</title>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/common.css"/>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/boardwrite.css"/>

</head>

<body>

<header> <!-- 헤더 영역 정의 -->

  <jsp:include page="../common/header.jsp" flush="false"/>

</header>

<section id="wrap"> <!-- 본문 영역 정의 -->

  <section id="lnav"> <!-- 사이드 메뉴 영역 정의 -->

    <jsp:include page="../common/lnav.jsp" flush="false"/>

  </section>

  <section id="content"> <!-- 내용 영역 정의 -->

    <h2>게시판 만들기</h2>

    <form action="<c:url value='write' />" method="post">

      게시판 이름: <input type="text" name="board_name" size="20"/> <br/>

      게시판 유형: <select name="board_type">

<option value="기본">기본</option>

<option value="Q&A">Q&#38A</option>

<option value="이미지">이미지</option>

<option value="공지사항">공지사항</option>

<option value="자료실">자료실</option>

<option value="방명록">방명록</option>

      </select><br>

      url : <input type="text" name="url" size="40"><br>

      비밀글 허용여부 : <input type="radio" name="secret" value="T">&nbsp;감추기&nbsp;&nbsp;&nbsp;

        <input type="radio" name="secret" value="F" checked="checked">&nbsp;보여주기<br>

      읽기 권한 : <select name="read_allow">

<option value="all">모두 허용</option>

<option value="login">로그인 후</option>

<option value="customer">고객</option>

<option value="business">상인</option>

<option value="admin">관리자</option>

      </select><br>

      쓰기 권한 : <select name="write_allow">

<option value="all">모두 허용</option>

<option value="login">로그인 후</option>

<option value="customer">고객</option>

<option value="business">상인</option>

<option value="admin">관리자</option>

      </select><br>

      댓글 쓰기 권한 : <select name="reply_allow">

<option value="all">모두</option>

<option value="login">로그인 후</option>

<option value="customer">고객</option>

<option value="business">상인</option>

<option value="admin">관리자</option>

      </select><br>

      수정 권한 : <select name="modify_allow">

<option value="all">모두</option>

<option value="login">로그인 후</option>

<option value="customer">고객</option>

<option value="business">상인</option>

<option value="writer">작성자</option>

<option value="admin">관리자</option>

      </select><br>

      삭제 권한 : <select name="remove">

<option value="writer">작성자</option>

<option value="admin">관리자</option>

      </select><br>

      다운로드 권한 : <select name="download">

<option value="all">모두</option>

<option value="login">로그인 후</option>

<option value="customer">고객</option>

<option value="business">상인</option>

<option value="admin">관리자</option>

      </select><br>

      업로드 권한 : <select name="upload">

<option value="all">모두</option>

<option value="login">로그인 후</option>

<option value="customer">고객</option>

<option value="business">상인</option>

<option value="admin">관리자</option>

      </select><br>

      첨부 파일 수 : <input type="number" name="nAttach" min="0" max="5"><br>

      첨부 파일 크기제한(한 개) : <select name="aSize">

<option value="0">0</option>

<option value="50KB">50KB</option>

<option value="200KB">200KB</option>

<option value="1MB">1MB</option>

<option value="10MB">10MB</option>

<option value="100MB">100MB</option>

      </select><br>

      내용 표시 형식 : <select name="display_format">

<option value="1">제목만 표시</option>

<option value="2">내용 일부 표시</option>

<option value="3">내용 전부 표시</option>

      </select><br>

      게시판 설명: <br/>

       <textarea name="board_desc" cols="80" rows="3"></textarea>

      <br/>

      <input id="addBtn" type="submit" value="전송" />

    </form>

  </section>

</section>

<footer> <!-- 풋터 영역 정의 -->

  <jsp:include page="../common/footer.jsp" flush="false"/>

</footer>

</body>

</html>



2.3 boardwrite.css : 위 그림과 같은 "게시판 만들기" view의 디자인 제공

@CHARSET "UTF-8";

#content form {

margin-top: 20px;

line-height: 1.5;

}

#content textarea {

line-height: 1.5;

}

#content #addBtn {

width: 200px;

font-size: 14px;

padding: 10px;

background-color: blue;

color: white;

border-radius: 5px 5px 5px 5px;

}


2.4 BoardController /manager/write (Post) 동작

  @RequestMapping(value="/write", method=RequestMethod.POST)

  public String writePro(BoardVO board) {    // 게시판 정보를 입력 받아

service.add(board);                         // 데이터베이스에 저장하고

return "redirect:/manager/list";          // 게시판 목록 보기로 이동

  }


2.5 게시판 추가 시 메뉴 변경

- 게시판을 추가하면 그에 따라 메뉴도 추가해 주어야 한다. 메뉴는 header.jsp에서 javascript로 처리를 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- 게시판 관리 기능에 의하여 게시판의 추가, 삭제, 변경 등에 대한 처리를 하는 javascript 파일 -->

<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/jquery-1.11.3.min.js"></script>

<script type="text/javascript" charset="utf-8" src="${pageContext.request.contextPath}/resources/js/header.js"></script>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/header.css"/>

<script type="text/javascript" charset="utf-8">

  sessionStorage.setItem("contextpath", "${pageContext.request.contextPath}");

</script>

<nav>

  <div id="gnbMenu">

    <ul id="gnb">

      <li class="item" id="item1">

<a href="" class="menu">지식창고</a>

<div class="sub" id="sub1">

  <ul class="subGnb" id="subGnb1">

    <!-- 게시판 추가로 인해 게시판 보기 메뉴가 추가될 영역 (javascript로 처리 : header.js)

    <li><a href="${pageContext.request.contextPath}/article/list?board_id=1&p=1">시 모음</a></li>

    -->

  </ul>

</div>

      </li>

      <li class="item" id="item2">

<a class="menu" href="<c:url value="/manager/list"/>">관리자</a>

      </li>

    </ul>

  </div>

</nav>


2.6 header.js

$(function() {

  var ctx = getContextPath();    // 프로젝트의 contextPath를 가져오는 부분

  getMenuInfo();                    // 서버로부터 메뉴처리를 위한 게시판 정보를 가져 온다.


  var gnbArea = document.getElementById("gnb");

  var menuItemAll = gnbArea.getElementsByTagName("li");

  var menuItem = new Array();

  var currentItem, prevItem;

  for(i=0;i<menuItemAll.length;i++){

    if((menuItemAll[i].className).indexOf("item") > -1){

      menuItem.push(menuItemAll[i]);

    }

  }


  for(i=0;i<menuItem.length;i++){

    var link = menuItem[i].getElementsByTagName("a")[0];

    var layer = menuItem[i].getElementsByTagName("div")[0];

    var subLinks = menuItem[i].getElementsByTagName("div")[0].getElementsByTagName("a");


    link.onmouseover = layer.onmouseover = link.onfocus = function(e){

      currentItem = this.parentNode;

      if(prevItem){

removeClass(prevItem,"on");

      }

      addClass(currentItem,"on");

      prevItem = currentItem;

    }

    link.onmouseout = layer.onmouseout = function(e){

      removeClass(this.parentNode,"on");

    }

    link.onkeydown = function(e){

      if (event.shiftKey && event.keyCode == 9){

  removeClass(this.parentNode,"on");

      }

    }

    for(j=0;j<subLinks.length;j++){

      subLinks[subLinks.length-1].onblur = function(e){

        removeClass(this.parentNode.parentNode.parentNode.parentNode,"on");

      }

    }

  }


  // 서버로부터 게시판에 대한 메뉴 처리를 위해 게시판 정보를 가져오는 부분

  function getMenuInfo() {        // 서버로 /manager/getMenuInfo 요청

    $.get(ctx + "/manager/getMenuInfo", function(data, status) {

      var str = "";

      $(data).each(function() {

        str += "<li><a href='" + ctx + "/article/list?board_id=" + this.board_id + "'>" + this.board_name + "</a></li>";

      });

      $('#subGnb1').html(str);

    });

  }


  // 프로젝트의 contextPath를 구하는 함수 : sessionStorage를 사용 (보통 header.jsp에서 script를 사용하여

  // sessionStorage에 contextPath를 저장하고, 이 파일에서 그것을 이용한다.

  function getContextPath() {

    return sessionStorage.getItem("contextpath");

  }

  // 액션 : 해당 클래스를 보여주기 위하여 on 클래스를 추가하는 루틴

  function addClass(ele, cls){

    var eleCln = ele.className;

    if(eleCln.indexOf(cls) == -1){

      ele.className = eleCln + " " + cls;

    }

  }


  // 해당 클래스를 안보이게 처리하기 위해 on class를 삭제하는 루틴

  function removeClass(ele, cls){

    var eleCln = ele.className;

    ele.className = eleCln.split(" " + cls)[0];

  }

});


2.7 서버에서 /manager/getMenuInfo 처리하는 부분

header.js에서 메뉴 처리를 위해 서버로 게시판 정보를 요청하는 /manager/getMenuInfo 부분이 있는데, 이에 대한 서버의 처리 부분이다.

  @RequestMapping(value="/getMenuInfo", method=RequestMethod.GET)

  public @ResponseBody List<MenuVO> getMenuInfo() {

List<MenuVO> list = service.getMenuInfo();

return list;

  }


- MenuVO 정의 : 메뉴 처리를 위해 필요한 정보를 나타낸다. (board_id, url, board_name)

package com.example.board.domain;


public class MenuVO {

private int board_id;             // 게시판 아이디 (게시판을 고유하게 식별)

private String url;                 // 게시글을 관리하기 위한 페이지로 이동을 위한 URL 정보

private String board_name;    // 메뉴에 표시되는 글

// getter, setter, toString() 등은 생략...

}


2.8 boardMapper.xml : 데이터베이스에서 MenuInfo를 추출하는 부분

  <!-- 게시판에 따른 메뉴 정보를 얻어내는 부분 -->

  <select id="getMenuInfo" resultType="com.example.board.domain.MenuVO">

    select board_id, url, board_name from board where board_id > 0 order by board_id desc

  </select>


Posted by 세상을 살아가는 사람
,