2023.12.06 - [백엔드(Back-End)/Spring Boot] - [sts4-Spring Boot] 12. Paging 페이지 블록 및 페이지 이동하기
페이징의 전반적인 기능을 추가했지만,
특정 글을 들어간 후(view) 다시 리스트로 돌아왔을 때 페이지 정보가 유지되지 않았었다.
이번 글에선 이전 페이지 정보를 유지하고자 한다.
특정 게시글의 정보와 관련한 코드를 수정하여, 이전 페이지 정보를 전달해주자~!
BoardController 의 openBoardDetail 메서드
- @ModelAttribute
: BoardDTO 객체를 뷰까지 전달
- BoardDTO : CommonDTO를 상속받고, 이는 Criteria를 상속 받아서 이전 페이지 정보가 담겨있다.
@GetMapping(value = "/board/view.do")
public String openBoardDetail(@ModelAttribute("params") BoardDTO params, @RequestParam(value="idx", required = false) Long idx, Model model) {
if (idx == null) {
return showMessageWithRedirect("올바르지 않은 접근입니다.", "/board/list.do", Method.GET, null, model);
}
BoardDTO board = boardService.getBoardDetail(idx);
if (board == null || "Y".equals(board.getDeleteYn())) {
return showMessageWithRedirect("없는 게시글이거나 이미 삭제된 게시글입니다.", "/board/list.do", Method.GET, null, model);
}
model.addAttribute("board", board);
return "board/view";
}
템플릿의 view.html
- view.html에 뒤로가기, 수정하기, 삭제하기 버튼을 눌렀을 때, 페이지 번호가 유지되어야 하므로
- th:object 속성 -> *{ } 표현식으로 메서드명, 변수명으로 객체에 접근 (컨트롤러에서 전달받은 객체)
<div class="btn_wrap text-center" th:object="${params}">
<a th:href="|@{/board/list.do}*{makeQueryString(currentPageNo)}|" class="btn btn-default waves-effect waves-light">뒤로가기</a>
<a th:href="|@{/board/write.do}*{makeQueryString(currentPageNo)}&idx=${board.idx}|" class="btn btn-primary waves-effect waves-light">수정하기</a>
<button type="button" class="btn btn-danger waves-effect waves-light" th:onclick="deleteBoard([[ ${board.idx} ]], [[ *{makeQueryString(currentPageNo)} ]])">삭제하기</button>
</div>
삭제하기 버튼을 누르면 실행되는 deleteBoard 함수도 수정한다.
- new URLSearchParams(queryString) : 쿼리 스트링에 포함된 모든 파라미터를 객체화
- 객체화된 queryString에 포함된 파라미터를 순환, 값 존재하는 것만 hidden 타입 폼에 추가
<th:block layout:fragment="script">
<script th:inline="javascript">
/*<![CDATA[*/
function deleteBoard(idx, queryString) {
if (confirm(idx + "번 게시글을 삭제할까요?")) {
var uri = /*[[ @{/board/delete.do} ]]*/ null;
var html = "";
html += '<form name="dataForm" action="'+uri+'" method="post">';
html += '<input type="hidden" name="idx" value="'+ idx +'"/>';
/*[- 쿼리 스트링을 오브젝트 형태로 변환 -]*/
queryString = new URLSearchParams(queryString);
queryString.forEach(function(value, key) {
if (isEmpty(value) == false) {
html += '<input type="hidden" name="' + key + '" value="'+ value +'" />';
}
});
html += '</form>';
$("body").append(html);
document.dataForm.submit();
}
}
/*]]>*/
</script>
</th:block>
UiUils 클래스에 getPagingParams 메서드 추가
- Criteria 클래스의 모든 멤버 변수(이전 페이지 정보)를 Map에 리턴
- POST 방식 처리에서만 사용
public Map<String, Object> getPagingParams(Criteria criteria) {
Map<String, Object> params = new LinkedHashMap<>();
params.put("currentPageNo", criteria.getCurrentPageNo());
params.put("recordsPerPage", criteria.getRecordsPerPage ());
params.put("pageSize", criteria.getPageSize());
params.put("searchType", criteria.getSearchType());
params.put("searchKeyword", criteria.getSearchKeyword());
return params;
}
BoardController 의 deleteBoard 메서드 변경
- BoardDTO 객체를 뷰로 전달
- getpagingParams 메서드 호출
- showMessageRedirect의 인자로 전달
@PostMapping(value = "/board/delete.do")
public String deleteBoard(@ModelAttribute("params") BoardDTO params, @RequestParam(value = "idx", required = false) Long idx, Model model) {
if (idx == null) {
return showMessageWithRedirect("올바르지 않은 접근입니다.", "/board/list.do", Method.GET, null, model);
}
Map<String, Object> pagingParams = getPagingParams(params);
try {
boolean isDeleted = boardService.deleteBoard(idx);
if (isDeleted == false) {
return showMessageWithRedirect("게시글 삭제에 실패하였습니다.", "/board/list.do", Method.GET, pagingParams, model);
}
} catch (DataAccessException e) {
return showMessageWithRedirect("데이터베이스 처리 과정에 문제가 발생하였습니다.", "/board/list.do", Method.GET, pagingParams, model);
} catch (Exception e) {
return showMessageWithRedirect("시스템에 문제가 발생하였습니다.", "/board/list.do", Method.GET, pagingParams, model);
}
return showMessageWithRedirect("게시글 삭제가 완료되었습니다.", "/board/list.do", Method.GET, pagingParams, model);
}
템플릿의 write.html
- 수정하기를 누르면 write.do로 넘어가므로, 해당 html에서도 페이지 번호 넘겨받기
- 쿼리스트링으로 페이지 번호를 전달
<div class="btn_wrap text-center" th:object="${params}">
<a th:href="|@{/board/list.do}*{makeQueryString(currentPageNo)}|" class="btn btn-default waves-effect waves-light">뒤로가기</a>
<button type="submit" class="btn btn-primary waves-effect waves-light">저장하기</button>
</div>
registerBoard 함수
function registerBoard(form) {
form.noticeYn.value = form.noticeYn.checked == false ? 'N' : 'Y';
form.secretYn.value = form.secretYn.checked == false ? 'N' : 'Y';
var result = (
isValid(form.title, "제목", null, null)
&& isValid(form.writer, "이름", null, null)
&& isValid(form.content, "내용", null, null)
);
if (result == false) {
return false;
}
var idx = /*[[ ${board.idx} ]] */ null;
if (isEmpty(idx) == false) {
var queryString = /*[[ ${params.makeQueryString(params.currentPageNo)} ]] */ null;
/*[- 쿼리 스트링을 오브젝트 형태로 변환 -]*/
queryString = new URLSearchParams(queryString);
queryString.forEach(function(value, key){
if (isEmpty(value) == false) {
$(form).append('<input type="hidden" name="' + key + '" value="' + value +'" />');
}
});
}
}
Board컨트롤러의 openBoardWrite 메서드
- BoardDTO 타입의 params 객체를 가져옴 ~> 화면에서 전달된 데이터 받아옴
- @RequestParam : URL에서 idx 파라미터 가져오기
- 없거나 삭제된 게시글이면 메시지와 함께 , 목록으로 리디렉션
- 수정할 글이 있으면 write 뷰를 반환
@GetMapping(value = "/board/write.do")
public String openBoardWrite(@ModelAttribute("params") BoardDTO params, @RequestParam(value = "idx", required = false) Long idx, Model model) {
if (idx == null) {
model.addAttribute("board", new BoardDTO());
} else {
BoardDTO board = boardService.getBoardDetail(idx);
if (board == null || "Y".equals(board.getDeleteYn())) {
return showMessageWithRedirect("없는 게시글이거나 이미 삭제된 게시글입니다.", "/board/list.do", Method.GET, null, model);
}
model.addAttribute("board", board);
}
return "board/write";
}
Board컨트롤러의 registerBoardWrite 메서드
- HTTP 요청으로 전송된 데이터를 BoardDTO 객체로 매핑 ~> 게시글 관련 정보 o
- getPagingParams(params) : 게시글 등록 후에도 이전 페이지로 리디렉션
- 예외 발생시, 메시지와 함께 게시판 목록 페이지로 리디렉션
@PostMapping(value ="/board/register.do")
public String registerBoard(@ModelAttribute("params") final BoardDTO params, Model model) {
Map<String, Object> pagingParams = getPagingParams(params);
try {
boolean isRegistered = boardService.registerBoard(params);
if (isRegistered == false) {
return showMessageWithRedirect("게시글 등록에 실패하였습니다.", "/board/list.do", Method.GET, pagingParams, model);
}
} catch (DataAccessException e) {
return showMessageWithRedirect("데이터베이스 처리 과정에 문제가 발생하였습니다.", "/board/list.do", Method.GET, pagingParams, model);
} catch (Exception e) {
return showMessageWithRedirect("시스템에 문제가 발생하였습니다.", "/board/list.do", Method.GET, pagingParams, model);
}
return showMessageWithRedirect("게시글 등록이 완료되었습니다.", "/board/list.do", Method.GET, pagingParams, model);
}
그럼 뒤로가기 / 수정하기 / 삭제하기 버튼을 눌러도 이전 페이지 번호가 유지된다.
'백엔드(Back-End) > Spring Boot' 카테고리의 다른 글
[sts4-Spring Boot] 16. REST 방식으로 댓글 CRUD (0) | 2023.12.07 |
---|---|
[sts4-Spring Boot] 15. REST API 사용해보기 (0) | 2023.12.07 |
[Spring Boot] 13. Searching 검색 기능(1) (0) | 2023.12.06 |
[sts4-Spring Boot] 12. Paging 페이지 블록 및 페이지 이동하기 (0) | 2023.12.06 |
[sts4-Spring Boot] 11. Alert Message 메시지 전달 (1) | 2023.12.05 |