이제 본격적으로 Controller와 view단을 구현해보겠습니다.
- BoardController에 페이징 기능을 하는 listPage 메서드 추가
- listPage.jsp 생성
BoardController 수정
<!-- BoardController.java -->
@RequestMapping(value = "/listPage", method = RequestMethod.GET)
public void listPage(Criteria cri, Model model) throws Exception {
logger.info("listPage!!!");
List<BoardVO> boards = service.listPage(cri);
model.addAttribute("list", boards);
PageMaker pageMaker = new PageMaker(cri);
int totalCount = service.totalCount(cri);
pageMaker.setTotalDataCount(totalCount);
model.addAttribute("pageMaker", pageMaker);
}
listPage 메서드에 의해 현재 페이지에 해당하는 게시물과 페이지번호를 나타내는 클래스인
PageMaker가 모델에 담겨 listPage.jsp로 전달됩니다.
<!-- listPage.jsp -->
<%@ 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/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
var register = "${register}";
if(register === "registerOK") {
alert("등록 되었습니다.");
}
var result = "${result}";
if(result === "deleteOK") {
alert("삭제 되었습니다.");
}
</script>
</head>
<body>
<div>
<a href="/board/register"><button>새글 작성</button></a>
</div>
<table>
<tr> <!-- 한줄 -->
<th>번호</th> <!-- 첫번째 칸 -->
<th>제목</th> <!-- 두번째 칸 -->
<th>작성자</th> <!-- 세번째 칸 -->
<th>작성일자</th> <!-- 네번째 칸 -->
<th>조회수</th>
</tr>
<c:forEach items="${list}" var="boardVO">
<tr>
<td>${boardVO.board_number}</td>
<td><a href="/board/read${pageMaker.makeQuery(pageMaker.cri.page)}&board_number=${boardVO.board_number}">${boardVO.title }</a></td>
<td>${boardVO.name}</td>
<td><fmt:formatDate pattern="YYYY-MM-dd" value="${boardVO.create_date}"/></td>
<td>${boardVO.view_count}</td>
</tr>
</c:forEach>
</table>
<!-- 페이지 번호 -->
<div>
<ul>
<!-- 맨처음 버튼 -->
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.firstPage)}">맨처음</a>
</li>
<!-- 이전 버튼 -->
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
</li>
<!-- 페이지 번호 (시작 페이지 번호부터 끝 페이지 번호까지) -->
<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var="idx">
<li>
<a href="listPage${pageMaker.makeQuery(idx)}">
<!-- 시각 장애인을 위한 추가 -->
<span>${idx}</span>
</a>
</li>
</c:forEach>
<!-- next 버튼 -->
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
</li>
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.finalPage)}">맨끝</a>
</li>
</ul>
</div>
</body>
</html>
이제 listPage.jsp를 출력해보겠습니다.
정상적으로 출력이 되지만 보기가 불편합니다.
편의를 위해 부트스트랩을 이용할건데요 다음과 같이 추가해주시면 됩니다.
<%@ 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/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
li {list-style: none; float: left; padding: 6px;}
a:link { color: black; text-decoration: none;}
a:visited { color: black; text-decoration: none;}
a:hover { color: blue; text-decoration: underline;}
th { text-align: center; }
table { text-align: center; }
h1 { padding: 40px}
</style>
<script>
var register = "${register}";
if(register === "registerOK") {
alert("등록 되었습니다.");
}
var result = "${result}";
if(result === "deleteOK") {
alert("삭제 되었습니다.");
}
</script>
</head>
<body>
<h1 align="center"><a href="/">게시판</a></h1><hr />
<div class="container">
<a href="/board/register"><button class="btn btn-primary">새글 작성</button></a>
</div>
<div class="container">
<table class="table table-bordered">
<tr> <!-- 한줄 -->
<th>번호</th> <!-- 첫번째 칸 -->
<th>제목</th> <!-- 두번째 칸 -->
<th>작성자</th> <!-- 세번째 칸 -->
<th>작성일자</th> <!-- 네번째 칸 -->
<th>조회수</th>
</tr>
<c:forEach items="${list}" var="boardVO">
<tr>
<td>${boardVO.board_number}</td>
<td><a href="/board/read${pageMaker.makeQuery(pageMaker.cri.page)}&board_number=${boardVO.board_number}">${boardVO.title }</a></td>
<td>${boardVO.name}</td>
<td><fmt:formatDate pattern="YYYY-MM-dd" value="${boardVO.create_date}"/></td>
<td>${boardVO.view_count}</td>
</tr>
</c:forEach>
</table>
</div>
<!-- 페이지 번호 -->
<div class="text-center">
<ul class="pagination">
<!-- 맨처음 버튼 -->
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.firstPage)}">맨처음</a>
</li>
<!-- 이전 버튼 -->
<c:if test="${pageMaker.prev}">
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
</li>
</c:if>
<!-- 페이지 번호 (시작 페이지 번호부터 끝 페이지 번호까지) -->
<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var ="idx">
<li <c:out value="${pageMaker.cri.page == idx ? 'class=active' : '' }"/>>
<a href="/board/listPage${pageMaker.makeQuery(idx)}">
<span>${idx}</span>
</a>
</li>
</c:forEach>
<!-- next 버튼 -->
<c:if test="${pageMaker.next}">
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
</li>
</c:if>
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.finalPage)}">맨끝</a>
</li>
</ul>
</div>
</body>
</html>
부트스트랩을 추가하고 다시 listPage를 조회하면
다음과 같이 깔끔해졌습니다.
저렇게 코드로만 올리면 보기 힘들기 때문에 수정한 점에 대해 설명하겠습니다.
1. 부트스트랩을 사용할 수 있도록 코드 추가
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
2. 게시판 목록 테이블 수정
<div class="container">
<table class="table table-bordered">
<tr> <!-- 한줄 -->
<th>번호</th> <!-- 첫번째 칸 -->
<th>제목</th> <!-- 두번째 칸 -->
<th>작성자</th> <!-- 세번째 칸 -->
<th>작성일자</th> <!-- 네번째 칸 -->
<th>조회수</th>
</tr>
<c:forEach items="${list}" var="boardVO">
<tr>
<td>${boardVO.board_number}</td>
<td><a href="/board/read${pageMaker.makeQuery(pageMaker.cri.page)}&board_number=${boardVO.board_number}">${boardVO.title }</a></td>
<td>${boardVO.name}</td>
<td><fmt:formatDate pattern="YYYY-MM-dd" value="${boardVO.create_date}"/></td>
<td>${boardVO.view_count}</td>
</tr>
</c:forEach>
</table>
</div>
- div 태그를 이용하여 class를 container로 설정 해주었는데 이유는 사용자가 보기 편하도록 알맞은 크기로 설정해줍니다.
- table 태그의 table table-bordered는 테이블 형식에 맞추어 꾸며주었습니다.
3. 페이지 번호
<!-- 페이지 번호 -->
<div class="text-center">
<ul class="pagination">
<!-- 맨처음 버튼 -->
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.firstPage)}">맨처음</a>
</li>
<!-- 이전 버튼 -->
<c:if test="${pageMaker.prev}">
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
</li>
</c:if>
<!-- 페이지 번호 (시작 페이지 번호부터 끝 페이지 번호까지) -->
<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var ="idx">
<li <c:out value="${pageMaker.cri.page == idx ? 'class=active' : '' }"/>>
<a href="/board/listPage${pageMaker.makeQuery(idx)}">
<span>${idx}</span>
</a>
</li>
</c:forEach>
<!-- next 버튼 -->
<c:if test="${pageMaker.next}">
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
</li>
</c:if>
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.finalPage)}">맨끝</a>
</li>
</ul>
</div>
<div class="text-center">
- div태그로 페이지 번호를 출력하는 부분을 감싸 가운데 정렬.
<ul class="pagination">
- 페이지 번호를 보기 편하도록 꾸밈.
<!-- 페이지 번호 부분 -->
<li <c:out value="${pageMaker.cri.page == idx ? 'class=active' : '' }"/>>
- JSTL의 c:out 태그로 삼항연산자를 사용해 page 번호와 idx(page 번호)가 같으면 부트스트랩의 'class=active'로 활성화 기능
<!-- 이전 버튼 -->
<c:if test="${pageMaker.prev}">
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.startPage-1)}">이전</a>
</li>
</c:if>
<!-- 다음 버튼 -->
<c:if test="${pageMaker.next}">
<li>
<a href="listPage${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a>
</li>
</c:if>
마찬가지로 JSTL의 if문을 이용하는데요.
pageMaker에서 다음과 같이 다음버튼과 이전 버튼을 작성한 것을 기억하시나요?
this.prev = startPage == 1? false : true;
this.next = (endPage * perPageNum) <= totalDataCount ? true : false;
다음과 같이 페이지 번호가 1이면 이전 페이지가 없기 때문에 false로 보이지 않도록 처리하고,
(끝페이지) * (보여지는 페이지 수) 보다 전체 데이터가 더 많으면 true 처리를 하여 다음버튼으로 갈 수 있도록 처리했습니다.
페이지 번호
예를 들어 시작페이지가 1이고 끝페이지가 10이라고 가정한다면
for문을 이용해 1, 2 ,3 .... 이렇게 출력이 되도록 하고
uriComponents를 이용하여 url을 생성해주면
해당 페이지(2)를 클릭했을 때
criteria의 getDataStart메서드가 실행되어
public int getDataStart() {
return (this.page - 1) * perPageNum;
}
mapper의 limit 부분이 실행되어 21번 데이터부터 10개가 출력이 됩니다.