Spring/게시판 만들기

[Camel][Spring] 게시판 만들기 #5-2. 페이징 처리 (Paging) 추가 사항

Camelll 2020. 6. 26. 19:07

[Camel][Spring] 게시판 만들기 #5-2. 페이징 처리 (Paging) 추가 사항

 

본 게시판 만들기 프로젝트는 더블에스 Devlog Spring-MVC 를 참조하여 작성했음을 알려드립니다. 또한 개인적인 학습을 목적으로한 포스팅이기 때문에 완벽하지 않을 수 있음을 알려드립니다. 문제점이나 궁금한점은 댓글로 남겨주시면 감사하겠습니다. 프로젝트 생성에 앞서 이번 게시판 만들기 프로젝트는 이클립스를 사용하여 구현하였습니다. 

 

이번 포스팅에서는 이전 포스팅에서 구현한 페이징 처리를 개선하고, uri를 좀더 나은 방식으로 제어할 수 있는 방법을 구현하겠습니다. 이를 위해 이번 포스팅에서는 UriComponentsBuilder를 사용해보도록 하겠습니다. 

 

1. UriComponentsBuilder

 Spring MVC에서는  Web개발에 필요한 다양한 유틸리티 클래스들을 제공하고 있는데, 그중에 URI를 작성할 때 도움을 주는 클래스로 UriComponentsBuilder UriComponents클래스가 있습니다. 

 

 PageMaker 클래스에 아래와 같은 메소드를 추가해주도록 하겠습니다. 

public String makeQuery(int page) {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
            .queryParam("page", page)
            .queryParam("perPageNum", criteria.getPerPageNum())
            .build();

    return uriComponents.toUriString();
}

makeQuery 메소드를 통해서 우리는 URI를 자동으로 생성할 수 있게됩니다. 그렇다면 이제 list_paging.jsp 파일의 Main content 부분을 아래와 같이 수정하겠습니다. 

<!-- Main content -->
<div class="content">
  <div class="container-fluid">
    <div class="col-lg-12">
      <div class="card">
        <div class="card-header">
          <h3 class="card-title">게시글 목록</h3>
        </div>
        <div class="card-body table-responsive p-0">
          <table class="table table-hover">
            <thead>
              <tr>
                <th style="width: 30px">#</th>
                <th>제목</th>
                <th style="width: 100px">작성자</th>
                <th style="width: 150px">작성시간</th>
                <th style="width: 60px">조회</th>
              </tr>
            </thead>
            <tbody>
              <c:forEach items="${articles}" var="article">
                <tr>
                  <td>${article.article_no}</td>
                  <td><a
                  href="${path}/article/read${pageMaker.makeQuery(pageMaker.criteria.page)}&article_no=${article.article_no}">${article.title}</a></td>
                  <td>${article.writer}</td>
                  <td><fmt:formatDate value="${article.regDate}"
                  pattern="yyyy-MM-dd" /></td>
                  <td><span class="badge bg-success">${article.viewCnt}</span></td>
                </tr>
              </c:forEach>
            </tbody>
          </table>
        </div>
        <div class="card-footer">
          <div class="float-right">
            <button type="button" class="btn btn-success btn-flat"
            id="writeBtn">
            	<i class="fa fa-pencil"></i> 글쓰기
            </button>
          </div>
        </div>
        <div class="card-footer">
          <nav aria-label="Contacts Page Navigation">
            <ul class="pagination justify-content-center m-0">
              <c:if test="${pageMaker.prev}">
                <li class="page-item"><a class="page-link"
                href="${path}/article/listPaging${pageMaker.makeQuery(pageMaker.startPage - 1)}">이전</a></li>
              </c:if>
              <c:forEach begin="${pageMaker.startPage}"
                end="${pageMaker.endPage}" var="idx">
                <li class="page-item"
                	<c:out value="${pageMaker.criteria.page == idx ? 'class=active' : ''}"/>>
                	<a class="page-link" href="${path}/article/listPaging${pageMaker.makeQuery(idx)}">${idx}</a>
                </li>
              </c:forEach>
              <c:if test="${pageMaker.next && pageMaker.endPage > 0}">
              	<li class="page-item"><a class="page-link"
              		href="${path}/article/listPaging?${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a></li>
              </c:if>
            </ul>
          </nav>
        </div>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</div>

 

2. 목록페이지 정보 유지

 다음으로는 특정 목록페이지에서 특정 게시글을 조회, 수정, 삭제한 뒤 다시 목록을 이동할 때 특정 목록페이지로 다시 이동하도록 구현해보겠습니다. 

 이를 위해 우선 컨트롤러에 아래의 수정된 조회, 수정, 삭제 메소드를 추가하겠습니다. 

@RequestMapping(value = "/readPaging", method = RequestMethod.GET)
public String readPaging(@RequestParam("article_no") int article_no,
                         @ModelAttribute("criteria") Criteria criteria,
                         Model model) throws Exception {

    model.addAttribute("article", articleService.read(article_no));

    return "/article/read_paging";
}

@RequestMapping(value = "/modifyPaging", method = RequestMethod.GET)
public String modifyGETPaging(@RequestParam("article_no") int article_no,
                              @ModelAttribute("criteria") Criteria criteria,
                              Model model) throws Exception {

    logger.info("modifyGetPaging ...");
    model.addAttribute("article", articleService.read(article_no));

    return "/article/modify_paging";
}

@RequestMapping(value = "/modifyPaging", method = RequestMethod.POST)
public String modifyPOSTPaging(ArticleVO articleVO,
                               Criteria criteria,
                               RedirectAttributes redirectAttributes) throws Exception {

    logger.info("modifyPOSTPaging ...");
    articleService.update(articleVO);
    redirectAttributes.addAttribute("page", criteria.getPage());
    redirectAttributes.addAttribute("perPageNum", criteria.getPerPageNum());
    redirectAttributes.addFlashAttribute("msg", "modSuccess");

    return "redirect:/article/listPaging";
}

@RequestMapping(value = "/removePaging", method = RequestMethod.POST)
public String removePaging(@RequestParam("article_no") int article_no,
                           Criteria criteria,
                           RedirectAttributes redirectAttributes) throws Exception {

    logger.info("remove ...");
    articleService.delete(article_no);
    redirectAttributes.addAttribute("page", criteria.getPage());
    redirectAttributes.addAttribute("perPageNum", criteria.getPerPageNum());
    redirectAttributes.addFlashAttribute("msg", "delSuccess");

    return "redirect:/article/listPaging";
}

이어서 조회, 수정, 삭제를 위한 JSP파일 또한 복사하여 read_paging.jsp, modify_paging.jsp, delete_paging.jsp로 만들어 줍니다. 

 

그리고 read_paging.jsp 파일을 아래와 같이 수정해줍니다.

<div class="card-footer">
    <form role="form" method="post">
        <input type="hidden" name="article_no" value="${article.article_no}">
        <input type="hidden" name="page" value="${criteria.page}">
        <input type="hidden" name="perPageNum" value="${criteria.perPageNum}">
    </form>
    <button type="submit" class="btn btn-primary listBtn"><i class="fa fa-list"></i> 목록</button>
    <div class="pull-right">
        <button type="submit" class="btn btn-warning modBtn"><i class="fa fa-edit"></i> 수정</button>
        <button type="submit" class="btn btn-danger delBtn"><i class="fa fa-trash"></i> 삭제</button>
    </div>
</div>
$(document).ready(function () {

    var formObj = $("form[role='form']");
    console.log(formObj);

    $(".modBtn").on("click", function () {
        formObj.attr("action", "${path}/article/modifyPaging");
        formObj.attr("method", "get");
        formObj.submit();
    });

    $(".delBtn").on("click", function () {
       formObj.attr("action", "${path}/article/removePaging");
       formObj.submit();
    });

    $(".listBtn").on("click", function () {
       formObj.attr("method", "get");
       formObj.attr("action", "${path}/article/listPaging");
       formObj.submit();
    });

});

 

modify_paging.jsp 파일도 아래와 같이 수정해줍니다.

<div class="box-body">
  <input type="hidden" name="article_no" value="${article.article_no}">
  <input type="hidden" name="page" value="${criteria.page}">
  <input type="hidden" name="perPageNum" value="${criteria.perPageNum}">
  <div class="form-group">
    <label for="title">제목</label> 
    <input class="form-control" id="title" name="title" placeholder="제목을 입력해주세요" value="${article.title}">
   </div>
   <div class="form-group">
    <label for="content">내용</label>
    <textarea class="form-control" id="content" name="content" rows="30" placeholder="내용을 입력해주세요" style="resize: none;">${article.content}</textarea>
   </div>
   <div class="form-group">
    <label for="writer">작성자</label> 
    <input class="form-control" id="writer" name="writer" value="${article.writer}" readonly>
  </div>
</div>
$(document).ready(function () {

    var formObj = $("form[role='form']");
    console.log(formObj);

    $(".modBtn").on("click", function () {
        formObj.submit();
    });

    $(".cancelBtn").on("click", function () {
        history.go(-1);
    });

    $(".listBtn").on("click", function () {
        self.location = "${path}/article/listPaging?page=${criteria.page}&perPageNum=${criteria.perPageNum}";
    });

});

 

3. 포스팅을 마치며

이번 포스팅에서는 간단하게 목록정보를 유지하고 URI 제어 방법에 대해 설명했습니다. 다음 포스팅에서는 게시글 검색에 대한 내용을 포스팅해보도록 하겠습니다.

 

다음포스팅

2020/06/26 - [Spring/게시판 만들기] - [Camel][Spring] 게시판 만들기 #번외. 프로젝트 진행에 따른 구조 변경

 

[Camel][Spring] 게시판 만들기 #번외. 프로젝트 진행에 따른 구조 변경

[Camel][Spring] 게시판 만들기 #번외. 프로젝트 진행에 따른 구조 변경 본 게시판 만들기 프로젝트는 더블에스 Devlog Spring-MVC 를 참조하여 작성했음을 알려드립니다. 또한 개인적인 학습을 목

cameldev.tistory.com

 

글을 읽으시면서 잘못된 부분이나 궁금하신 사항은 댓글 달아주시면 빠른 시일내에 수정 및 답변하도록 하겠습니다.