앞에서 기술했던 부분에 이어 특정 게시판에 대한 관리 기능(게시글 목록 보기, 게시글 추가)을 기술한다. 다른 기능(게시글 수정, 게시글 삭제, 게시글 읽기)은 기술하지 않았다.

1. 게시글 목록 보기

- 헤더의 메뉴 중 "지식창고"에 마우스를 갖다대면 서브 메뉴가 나타난다. 이는 추가된 게시판에 대한 게시글 관리 기능으로의 링크이다. 이 링크를 누르면 해당 게시판에 대한 게시글 관리창으로 이동하게 된다.

예를 들어, "Web"이라는 서브 메뉴를 누르면 "http://localhost:8080/board/article/list?board_id=1"로 이동하게 된다.

1.1 ArticleController에서 /article/list에 대한 처리

package com.example.board.controller;


import javax.inject.Inject;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import com.example.board.domain.ArticleVO;

import com.example.board.domain.Criteria;

import com.example.board.domain.PageMaker;

import com.example.board.service.ArticleService;

import com.example.board.service.BoardService;


@Controller

@RequestMapping(value="/article")

public class ArticleController {

@Inject

public ArticleService service;    // 게시글 관리 기능을 처리하기 위한 Service

@Inject

public BoardService bService;    // 게시판 관리 기능을 처리하기 위한 Service

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

public void list(int board_id, Criteria cri, Model model) throws Exception {

model.addAttribute("board", bService.read(board_id));    // 해당 게시판에 대한 정보를 획득

model.addAttribute("list", service.list(cri));      // 해당 게시판의 게시글 목록 정보를 가져온다.

PageMaker pm = new PageMaker();            // 페이징 처리를 위한 인스턴스를 만든다.

pm.setCri(cri);                                         // 페이징 처리를 위한 기준 정보를 저장

pm.setTotalCount(service.listCount());           // 해당 게시판의 전체 게시글의 수를 얻는다.

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

}


1.2 list.jsp : 게시글 목록 보기 화면


<%@ 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" %>

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

<!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>게시판 이름 : ${board.board_name}</h1>

    <table>

      <c:if test="${pageMaker.totalCount > 0}"><!-- 게시글이 있는지 검사 -->

      <tr>

<td colspan="5"><!-- 페이지에 대한 정보를 표시 -->

  ${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="5">

    게시글이 없습니다.

  </td>

</tr>

      </c:when>

      <c:otherwise>

<tr><!-- 게시글에 대한 표시 타이틀 부분 -->

  <td class="title_head" width="9%">번호</td>

  <td class="title_head" width="54%">제목</td>

  <td class="title_head" width="11%">작성자</td>

  <td class="title_head" width="17%">작성일</td>

  <td class="title_head" width="9%">조회수</td>

</tr>

<c:forEach var="article" items="${list}"><!-- 각 게시글에 대하여 -->

    <tr>

      <td>${article.article_id}</td>

      <td width="40%">

<c:if test="${article.depth > 0}"><!-- 댓글에 대한 depth 표시 -->

  <c:forEach begin="1" end="${article.depth}">-</c:forEach>&gt;

</c:if>

<c:if test="${article.secret == 'T'}"><!-- 제목 처리 (비밀글 여부에 따라 다르게 처리)-->

  <c:choose>

  <c:when test="${sessionScope.member.category == 'admin'}">

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

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

    <a href="<c:url value="/article/read?${query}"/>">${fn:substring(article.title, 0, 28)}</a>

  </c:when>

  <c:when test="${sessionScope.id == article.email}">

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

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

    <a href="<c:url value="/article/read?${query}"/>">${fn:substring(article.title, 0, 28)}</a>

  </c:when>

  <c:otherwise>

    ${fn:substring(article.title, 0, 28)}

  </c:otherwise>

  </c:choose>

  &nbsp;<img width="13px" height="13px" alt="*" src="<c:url

   value="/resources/images/secret_image.png"/>">

        </c:if>

        <c:if test="${article.secret != 'T'}">

  <c:choose>

  <c:when test="${board.read_allow == 'all'}">

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

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

    <a href="<c:url value="/article/read?${query}"/>">${fn:substring(article.title, 0, 28)}</a>

  </c:when>

  <c:when test="${board.read_allow == 'login' && sessionScope.id != null}">

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

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

    <a href="<c:url value="/board/read?${query}"/>">${fn:substring(article.title, 0, 28)}</a>

  </c:when>

  <c:when test="${board.read_allow == 'login' && sessionScope.id == null}">

    ${fn:substring(article.title, 0, 28)}

  </c:when>

  <c:when test="${sessionScope.id != null && sessionScope.member.category == 

    board.read_allow}">

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

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

    <a href="<c:url value="/article/read?${query}"/>">${fn:substring(article.title, 0, 28)}</a>

  </c:when>

  <c:otherwise>

    ${fn:substring(article.title, 0, 28)}

  </c:otherwise>

          </c:choose>

        </c:if>

      </td>

      <td>${article.writer_name}</td>

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

      <td>${article.read_count}</td>

    </tr>

    <c:choose>

    <c:when test="${board.display_format==2}"><!-- 본문의 표시 방법 처리 -->

      <tr>

        <td colspan="5">${fn:substring(article.content, 0, 200)}</td>

      </tr>

    </c:when>

    <c:when test="${board.display_format==3}">

      <tr>

        <td colspan="5">${article.content}</td>

      </tr>

    </c:when>

            </c:choose>

          </c:forEach>

          <tr>

            <td colspan="5"><!-- 페이징 처리(링크 표시) -->

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

  <a href="<c:url value="/article/list?board_id=${board.board_id}&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="/article/list?board_id=${board.board_id}&page=${pno}

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

        </c:forEach>

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

  <a href="<c:url value="/article/list?board_id=${board.board_id}&page=

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

              </c:if>

            </td>

          </tr>

        </c:otherwise>

</c:choose>

      <c:choose><!-- 글쓰기 권한에 따른 글쓰기 허용여부 처리 -->

<c:when test="${board.write_allow == 'all'}">

  <tr>

    <td colspan="5"><a href="write?board_id=${board.board_id}">글쓰기</a></td>

  </tr>

</c:when>

<c:when test="${board.write_allow == 'login' && sessionScope.id != null}">

  <tr>

    <td colspan="5"><a href="write?board_id=${board.board_id}">글쓰기</a></td>

  </tr>

</c:when>

<c:when test="${sessionScope.id != null && sessionScope.member.category == 

board.write_allow}">

  <tr>

    <td colspan="5"><a href="write?board_id=${board.board_id}">글쓰기</a></td>

  </tr>

</c:when>

      </c:choose>

    </table>

  </section>

</section>

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

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

</footer>

</body>

</html>


게시글 쓰기 링크를 누르면 게시글 쓰기로 이동한다. (/article/write)


1.3 ArticleController /article/write 처리

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

  public String write(int board_id, Model model) {

model.addAttribute("board", bService.read(board_id)); // 해당 게시판에 대한 정보를 획득

return "/article/writeForm"; // 게시글 입력 창으로 이동

  }


1.4 writeForm.jsp : 게시글 입력 폼 화면


위 그림과 같이 게시글 쓰기 입력 창을 보여준다.

<%@ 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/articlewrite.css"/>

<script type="text/javascript" src="<c:url value="/resources/js/jquery-1.11.3.min.js"/>"></script>

<script type="text/javascript" charset="utf-8" src="<c:url value="/resources/js/articlewrite.js"/>"></script>

</head>

<body>

<c:choose>

<c:when test="${param.article_id != null}">

<c:set var="num" value="${param.article_id}"/>

<c:set var="ref" value="${param.ref}"/>

<c:set var="step" value="${param.step}"/>

<c:set var="depth" value="${param.depth}"/>

</c:when>

<c:otherwise>

<c:set var="num" value="0"/>

<c:set var="ref" value="1"/>

<c:set var="step" value="0"/>

<c:set var="depth" value="0"/>

</c:otherwise>

</c:choose>

<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"> <!-- 내용 영역 정의 -->

    <c:if test="${num == 0}">

      <h2>게시글 작성</h2>

    </c:if>

    <c:if test="${num != 0}">

      <h2>댓글 작성</h2>

    </c:if>

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

      <input type="hidden" name="board_id" value="${param.board_id}">

      <input type="hidden" name="num" value="${num}">

      <input type="hidden" name="ref" value="${ref}">

      <input type="hidden" name="step" value="${step}">

      <input type="hidden" name="depth" value="${depth}">

      <input type="hidden" name="author" value="">

      <table>

<tr>

  <td>제목: </td>

  <td>

    <c:if test="${num == 0}">

      <input type="text" name="title" size="90" maxlength="60" placeholder="제목을 입력 하십시

요." required/>

    </c:if>

    <c:if test="${num != 0}">

      <input type="text" name="title" size="90" maxlength="60" value="[답변]"/>

    </c:if>

  </td>

</tr>

<c:if test="${sessionScope.id != null}">

  <tr>

    <td>작성자: </td>

    <td><label>${sessionScope.member.nickname}</label></td>

  </tr>

  <input type="hidden" name="writer_name" value="${sessionScope.member.nickname}"/>

  <input type="hidden" name="email" value="${sessionScope.member.id}">

  <input type="hidden" name="password" value="${sessionScope.member.password}"/>

</c:if>

<c:if test="${sessionScope.id == null}">

  <tr>

    <td>작성자: </td>

    <td><input type="text" name="writer_name" /></td>

  </tr>

  <input type="hidden" name="email" value="이메일">

  <tr>

    <td>글암호: </td>

    <td><input type="password" name="password" /></td>

  </tr>

</c:if>

<tr>

  <td style="margin:0; padding:0;" colspan="2"><textarea name="content" rows="5" cols="80" 

  style="width:100%; height:212px;"></textarea></td>

</tr>

      </table>

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

    </form>

  </section>

</section>

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

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

</footer>

</body>

</html>


1.5 articlewrite.js : 첨부 파일을 5개 까지 추가할 수 있도록 dynamic하게 파일 첨부 버튼을 조작

  생략


[마치며] 처음에는 잘 정리해야 겠다고 생각을 했는데, 내용이 방대하여 마음의 여유가 없어지고, 조급해져 일부 내용을 빠트리고 정리가 된 것 같다. 글쎄 다른 사람이 이글을 보고 이해할 수 있을지 염려도 되지만 source code를 추가로 첨부해 본다.

bdmanager.zip


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