본문 바로가기
Website Production

Spring 홈페이지 - (14) 게시판 페이징 쿼리스트링 작업

by GoodDayDeveloper 2021. 3. 1.
반응형

지난 시간 페이징 작업에 이어 페이징 쿼리스트링을 해보도록 하겠습니다.

3번 페이지 버튼을 누르면 주소창에 아래와 같이 뜹니다.

http://localhost:8080/board/list?pageIndex=3&searchKeyword=

 

list에 물음표 ? 뒤에있는 값들 즉, 파라미터(변수를 던진 값)을 통해서 페이징이 가능한거죠

 

그런데 게시판들 들어가보면 게시판 인덱스 뒤에 아무것도 붙어 있지가 않습니다.

파라미터 값을 가지고 오지 못한 거죠!!

 

결국 목록을 누르면 3번 페이지 화면이 아닌, 1번 페이지의 처음 시작화면이 되게 됩니다.

 

 

즉, 3번페이지에서 게시글을 눌러서 작업을 완료하고 목록을 눌렀을 경우 3번페이지로 유지되기 위한 작업

파라미터 값을 계속해서 넘겨주는 작업을  QeuryString (쿼리스트링) 이라고 합니다.

이젠 쿼리스트링을 만들어보도록 하겠습니다!


PageVO

 

pageVO에 쿼리스트링 변수를 만들어주고 setter를 선언해준 다음 안에 코드를 넣어주면 됩니다.

검색 키워드인 searchKeyword와 페이지 인덱스가 필요합니다.

문자열이 들어가는 searchKeyword는 인코딩처리를 해줍니다.

(searchKeyword는 쿼리스트링으로 인하여 boardVO에서 pageVO로 옮겨왔습니다.)

 

public class PageVO {

private int pageIndex = 1;				//현재페이지
private int pageUnit = 10;				//페이지갯수
private int pageSize = 10;				//페이지사이즈
private int firstIndex = 1;				//firstIndex
//private int lastIndex = 1;			//lastIndex
private int recordCountPerPage = 10;	//recordCountPerPage
private int totCnt = 0;					//총갯수
private int startDate = 0;				//시작데이터
private int endDate = 0;				//종료데이터


private boolean prev, next;				//이전,다음버튼


//검색
  private String searchKeyword = "";
  
  //QueryString
  private String queryString = "";
  
  
  public void setQueryString() throws UnsupportedEncodingException {
	String qs = "";
	qs += "&searchKeyword="+URLEncoder.encode(this.searchKeyword, "UTF-8");
	qs += "&pageIndex="+this.pageIndex;
	
	this.queryString = qs;
	
}

 

boardVO

 

그리고 boardVO에서 qustr란 변수를 만들어준 다음 setter에 넣어줍니다.

public class boardVO extends PageVO {

private int board_idx;
  private String board_title;
  private String board_content;
  private String board_writer;
  private String board_regdate;
  private String board_updatedate;
  
  private String qustr;
  
  
  public void setQustr() throws UnsupportedEncodingException {
	
  	String qs = "";
  	this.setQueryString();
  	qs += this.getQueryString();
  	this.qustr = qs;
}

 

boardController

 

그리고 컨트롤러에 searchVO.setQustr(); 을 하단에 넣어줍니다. 

조금 전에 만든 것을 사용할 수 있도록요.

리스트/조회/수정/삭제 페이지 다 선언해줘야 조회/수정/삭제 할때도 파라미터 값이 유지될 수 있도록 하는거죠.

그리고 수정 액션이나 삭제 액션에서 리다이렉트에 이 값을 뒤에 넣어줘야 값을 가지고 원래 페이지로 이동할 수 있기 때문에 값 뒤에 설정해줍니다.

 

@Controller
public class BoardController {

@Autowired
private BoardService boardService;

@RequestMapping(value = "/board/list", method = RequestMethod.GET)
public String list(@ModelAttribute("searchVO") boardVO searchVO, HttpServletRequest request, Model model) throws UnsupportedEncodingException {
	
	Map<String, ?> inputFlashMap = RequestContextUtils.getInputFlashMap(request);
    if(null != inputFlashMap) {
    	
    	model.addAttribute("msg",(String) inputFlashMap.get("msg"));
    	
    }
	
    //페이징[s]
    Pagination pagination = new Pagination();
    pagination.setCurrentPageNo(searchVO.getPageIndex());
    pagination.setRecordCountPerPage(searchVO.getPageUnit());
    pagination.setPageSize(searchVO.getPageSize());
    
    searchVO.setFirstIndex(pagination.getFirstRecordIndex());
    searchVO.setRecordCountPerPage(pagination.getRecordCountPerPage());
    
	List<boardVO> boardList = boardService.getList(searchVO);
	int totCnt = boardService.getListCnt(searchVO);
	
	pagination.setTotalRecordCount(totCnt);
	
	searchVO.setEndDate(pagination.getLastPageNoOnPageList());
    searchVO.setStartDate(pagination.getFirstPageNoOnPageList());
    searchVO.setPrev(pagination.getXprev());
    searchVO.setNext(pagination.getXnext());
	
	model.addAttribute("boardList",boardList);
	model.addAttribute("totCnt",totCnt);
	model.addAttribute("totalPageCnt",(int)Math.ceil(totCnt / (double)searchVO.getPageUnit()));
	model.addAttribute("pagination",pagination);
	//페이징[e]
	
	searchVO.setQustr();
	
	return "/board/list";
}


@RequestMapping(value = "/board/read", method = RequestMethod.GET)
public String read(@ModelAttribute("searchVO") boardVO searchVO, @RequestParam("board_idx") int board_idx, Model model, HttpServletRequest request) throws UnsupportedEncodingException {
	
	Map<String, ?> inputFlashMap = RequestContextUtils.getInputFlashMap(request);
    if(null != inputFlashMap) {
    	
    	model.addAttribute("msg",(String) inputFlashMap.get("msg"));
    	
    }
	
	boardVO boardContents = boardService.getBoardContents(board_idx);
	model.addAttribute("boardContents", boardContents);
	
	searchVO.setQustr();
	
	return "/board/read";
}

@RequestMapping(value = "/board/update", method = RequestMethod.GET)
public String update(@ModelAttribute("searchVO") boardVO searchVO, @RequestParam("board_idx") int board_idx, Model model) throws UnsupportedEncodingException {
	
	boardVO boardContents = boardService.getBoardContents(board_idx);
	model.addAttribute("boardContents", boardContents);
	
	searchVO.setQustr();
	
	return "/board/update";
}


@RequestMapping(value = "/board/update_action", method = RequestMethod.POST)
public String update_action(@ModelAttribute("searchVO") boardVO searchVO, HttpServletRequest request, RedirectAttributes redirect , Model model) throws UnsupportedEncodingException{
	
	
	try {
	
	boardService.updateBoard(searchVO);
	redirect.addFlashAttribute("redirect", searchVO.getBoard_idx());
	redirect.addFlashAttribute("redirect", searchVO.getQustr());
	
	redirect.addFlashAttribute("msg", "수정이 완료되었습니다.");
		
	} catch (Exception e) {
	
	redirect.addFlashAttribute("msg", "오류가 발생되었습니다.");
	
	}
	
	searchVO.setQustr();
	
	return "redirect:/board/read?board_idx=" + searchVO.getBoard_idx() + "&" + searchVO.getQustr();
}

@RequestMapping(value = "/board/delete", method = RequestMethod.GET)
public String delete(@ModelAttribute("searchVO") boardVO searchVO, @RequestParam("board_idx") int board_idx, RedirectAttributes redirect , Model model) throws UnsupportedEncodingException {
	
	try {
		
		boardService.getBoardDelete(board_idx);
		redirect.addFlashAttribute("msg", "삭제가 완료되었습니다.");
		
	} catch (Exception e) {
		redirect.addFlashAttribute("msg", "오류가 발생되었습니다.");
		
	}
	
	searchVO.setQustr();
	
	return "redirect:/board/list?" + searchVO.getQustr();
}


}

 

 

반응형

 

 

list.jsp

 

리스트에서는 게시글 누를때 사용되네요

 

<table class="table table-bordered" width="100%" cellspacing="0" style="text-align:center;">
  <thead>
      <tr>
          <th>번호</th>
          <th>제목</th>
          <th>작성자</th>
          <th>등록일</th>
      </tr>
  </thead>
  <c:forEach var="list" items="${boardList}">
  	<tr>
  		<td><c:out value="${list.board_idx}" /></td>
  		<td>
  		<a href="/board/read?board_idx=${list.board_idx}&${searchVO.qustr}" >
  		<c:out value="${list.board_title}" />
  		</a>
  		</td>
  		<td><c:out value="${list.board_writer}" /></td>
  		<td><c:out value="${list.board_regdate}" /></td>
  	</tr>
  </c:forEach>
  </tbody>
</table>

 

read.jsp

 

상세페이지에서는 목록으로 갈때나 수정 작업을 할때 사용됩니다.

그리고 삭제버튼 누를때도 쿼리를 가지고 가네요!

 

<div style="margin-left:1px;">
	<a href="/board/list?&${searchVO.qustr}" class="btn btn-primary">목록</a>
	<a href="/board/update?board_idx=${boardContents.board_idx}&${searchVO.qustr}" class="btn btn-success">수정</a>
	<a href="javascript:void(0);" class="btn btn-danger" onclick="deleteConfirm();">삭제</a>
</div>
function deleteConfirm(){
	
	if(!confirm("삭제 하시겠습니까?")){
		return false;
	}else{
		location.href="${path}/board/delete.do?board_idx=${boardContents.board_idx}&${searchVO.qustr}";
	}
}

 

update.jsp

 

업데이트에서는 submit할때 값을 가져가기 위해서 form 아래에 input hidden으로 설정해주고

취소버튼 눌러 상세페이지로 갈때 쿼리값을 설정해줍니다.

 

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
<div class="panel-body">
<form role="form" action="/board/update_action" method="post" onsubmit="return _onSubmit();" >
<input type="hidden" id="board_idx" name="board_idx" value="${boardContents.board_idx }"/>
<input type="hidden" id="qustr" name="qustr" value="${searchVO.qustr}"/>
 
<div class="table-responsive" style="text-align:center;">
<table id="datatable-scroller"
class="table table-bordered tbl_Form">
<caption></caption>
<colgroup>
    <col width="250px" />
    <col />
</colgroup>
<tbody>
    <tr> 
        <th class="active">제목</th>
        <td class="form-inline"><input type="text" id="board_title"
            name="board_title" class="form-control" style="width: 840px" value="${boardContents.board_title }"/>
        </td>
    </tr>
    <tr>
        <th class="active" >작성자</th>
        <td class="form-inline"><input type="text" id="board_writer"
            name="board_writer" class="form-control" style="width: 200px" value="${boardContents.board_writer }"/>
        </td>
    </tr>
    <tr>
        <th class="active" >내용</th>
        <td class="form-inline"><textarea 
                id="board_content" name="board_content" cols="100" rows="10"
                class="form-control">${boardContents.board_content }</textarea></td>
    </tr>
</tbody>
</table>
</div>
<div style="margin-left:1px;">
<button type="submit" class="btn btn-success">수정</button>
<a href="/board/read?board_idx=${boardContents.board_idx}&${searchVO.qustr}" class="btn btn-danger">취소</a>
</div>
</form>
cs

 

 

이렇게 하면 화면이 넘어갈때마다 쿼리값을 가지고와서 페이지가 유지될 수 있는거죠!!

 

 

 

list.jsp 전체소스

 

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
<%@ 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" %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
 
$(document).ready(function() {
 
var thisIndex = "${searchVO.pageIndex}"
$(".pagination li a").each(function(){
var idx = $(this).parent().index();
var thistitle = $(this).attr("title");
if(thistitle == thisIndex){
$(".pagination").find("li").eq(idx).addClass("active");
}
});
 
 
 
var msg = "${msg}";
 
if(msg != ""){
alert(msg);    
}
 
});
 
function fn_go_page(pageNo) {
$("#pageIndex").val(pageNo);
$("#listForm").submit();
return false;
}
 
function fn_search(){
$("#pageIndex").val("1");
$("#listForm").submit();
return false;
}
 
</script>
 
<%@include file="../includes/header.jsp" %>
 
<form method="get"  id="listForm" action="/board/list">
<input type="hidden" id="pageIndex" name="pageIndex" val="" />
<!-- Begin Page Content -->
<div class="container-fluid">
 
<!-- Page Heading -->
<h1 class="h3 mb-2 text-gray-800">Tables</h1>
<p class="mb-4">DataTables is a third party plugin that is used to generate the demo table below.
For more information about DataTables, please visit the <a target="_blank"
href="https://datatables.net">official DataTables documentation</a>.</p>
 
<!-- DataTales Example -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">DataTables Example</h6>
</div>
<!-- 검색[s] -->
<div class="card-header py-3">
<input type="text" id="searchKeyword" name="searchKeyword" value="${searchVO.searchKeyword}" style="width:300px; height:40px;" placeholder="검색어를 입력하세요." />
<a href="javascript:void(0)" onclick="fn_search(); return false;" class="btn btn-primary">검색</a>
</div>
<!-- 검색[e] -->
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="dataTable_info" role="status" aria-live="polite">
<span>총게시물 ${totCnt} / 페이지 (${searchVO.pageIndex} / ${totalPageCnt})</span>
</div></div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered" width="100%" cellspacing="0" style="text-align:center;">
    <thead>
        <tr>
            <th>번호</th>
            <th>제목</th>
            <th>작성자</th>
            <th>등록일</th>
        </tr>
    </thead>
    <c:forEach var="list" items="${boardList}">
        <tr>
            <td><c:out value="${list.board_idx}" /></td>
            <td>
            <a href="/board/read?board_idx=${list.board_idx}&${searchVO.qustr}" >
            <c:out value="${list.board_title}" />
            </a>
            </td>
            <td><c:out value="${list.board_writer}" /></td>
            <td><c:out value="${list.board_regdate}" /></td>
        </tr>
    </c:forEach>
    </tbody>
</table>
 
 <!-- Paging[s] -->
 
 <div class="col-sm-12 col-md-7" style="text-align:right">
  <div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate">
    <ul class="pagination">
    
    <c:if test="${searchVO.prev}">
    <li class="paginate_button page-item previous" id="dataTable_previous">
            <a href="javascript:void(0);" onclick="fn_go_page(${searchVO.startDate - 1}); return false;" aria-controls="dataTable" data-dt-idx="0" tabindex="0" class="page-link">Previous</a>
    </li>
    </c:if>
    
    <c:forEach var="num" begin="${searchVO.startDate}" end="${searchVO.endDate}">
    <li class="paginate_button page-item">
            <a href="javascript:void(0);" onclick="fn_go_page(${num}); return false;" aria-controls="dataTable" data-dt-idx="0" tabindex="0" class="page-link" title="${num}">${num}</a>
    </li>
    </c:forEach>
    
    <c:if test="${searchVO.next}">
    <li class="paginate_button page-item next" id="dataTable_next">
            <a href="javascript:void(0);" onclick="fn_go_page(${searchVO.endDate + 1}); return false;" aria-controls="dataTable" data-dt-idx="0" tabindex="0" class="page-link">Next</a>
    </li>
    </c:if>
    </ul>
  </div>
</div>
<!-- Paging[e] -->
 
<a href="/board/create" class="btn btn-primary" >등록</a>
</div>
</div>
</div>
</div>
<!-- /.container-fluid -->
 
</form>
 
<%@include file="../includes/footer.jsp" %>
 
 
cs

 

 

 


 

항목을 클릭하시면 해당 페이지로 이동합니다.
Spring 웹 홈페이지 개발 과정 리스트 (1) 자바설치 및 환경변수 설정
(2) 이클립스 및 스프링 설치
(3) 톰캣설치 방법
(4) 이클립스 자바 환경설정 및 인코딩 설정방법
(5) 데이터베이스(Mysql) 설치
(6) 프로젝트 환경설정
(7) 홈페이지 디자인 적용
(8) 게시판 목록 페이지 작업
(9) 게시판 등록 페이지 작업
(10) 게시판 상세보기 페이지 작업
(11) 게시판 수정/삭제 페이지 작업
(12) 게시판 검색 페이지 작업
(13) 게시판 페이징 작업
(14) 게시판 페이징 쿼리스트링 작업
(15) 회원가입 작업 (feat.아이디 중복체크/비밀번호 암호화)
(16) 로그인/로그아웃 작업 (feat.아이디 기억하기)
(17) 아이디&비밀번호 찾기
(18) 마이페이지 정보&비밀번호 수정

 

 

 

반응형

댓글