데일리로그C:
article thumbnail

예외처리

1. CommonExceptionAdvice.java --> controller에

package org.zerock.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

//@ControllerAdvice //이 클래스가 객체가 컨트롤러에서 발생하는 Exception을 전문적으로 처리하는 클래스(프로젝트 젤 마지막에 넣을 것!)
public class CommonExceptionAdvice {
	private static final Logger logger = LoggerFactory.getLogger(CommonExceptionAdvice.class);
	
	@ExceptionHandler(Exception.class)
	public String common(Exception e) { //common() 메소드를 이용해서 Exception 타입으로 처리되는 모든 예외를 처리하도록 설정된다.
		logger.info("common()......에러처리 부분...");
		logger.info(e.toString());

		return "/error_common"; // 절대경로로 forward
		
		 //http://localhost:8080/board/read?bno=1634 (잘못된 값으로 테스트 확인)
         // 주소는 그대로지만 error_common.jsp 를 보여줌
	}
}

 

2. error_common.jsp --> view에

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
공사중입니다. <br>
잘못된 경로로 들어왔습니다.
</center>
</body>
</html>

 

페이징 처리

  ㄴ> limit 두 변수 없이 page 변수 하나를 계속 전달 

1. 변수처리

1) BoardDAO.java --> 한줄 추가

public List<BoardVO> listPage(int page) throws Exception; // 페이징

 

2) BoardDAOImpl.java --> 추가

@Override //추가
public List<BoardVO> listPage(int page) throws Exception {
    if(page <= 0) {
        page = 1;
    }
    page = (page - 1) * 10; //limit 첫번째 항목

    return session.selectList(namespace+".listPage", page);
}

 

3) boardMapper.xml --> 추가

	<select id="listPage" resultType="BoardVO">
	<!-- resultType="BoardVO" 줄여서 사용할 수 있는 이유 -->
	<!-- mybatis-config.xml에서 <typeAliases> 추가 했기 때문이다. -->
	<![CDATA[
		select * from tbl_board where bno > 0 order by bno desc, regdate desc limit #{page}, 10
	]]>
	</select>

 

4) BoardDAOTest.java ( 테스트 )

@Test //페이징 테스트
	public void testListPage() throws Exception {
		int page = 1;

		List<BoardVO> list = dao.listPage(page);

		for (BoardVO boardVO : list) {
			logger.info(boardVO.getBno() + ":" + boardVO.getTitle());
		}
	}

 

2. 객체 처리

 ㄴ> Criteria 클래스 생성 --> 페이징 limit 담당

 

1) Criteria.java --> domain에

package org.zerock.domain;

public class Criteria {

	private int page; // limit ?,0에 해당(첫번째 변수)
	private int perPageNum; // limit 0,? 에 해당(두번째 변수)
	
	// 초기화
	public Criteria() { //첫페이지 실행시 적용될 값들 (기본 생성자)
		this.page = 1; //첫 페이지 초기화
		this.perPageNum = 10; //한 페이지당 출력 할 게시물 수
	}
	
	
	// set,get page
	public void setPage(int page) { // get 방식으로 페이지 값이 초기화 안되어있다면
		if(page <= 0) {
			this.page = 1;
			return;
		}
		this.page = page; // get 방식으로 넘어온 값을 전역변수에 전달
	}	
	public int getPage() {
		return page;
	}
	
	
	// perPageNum set,get
	//Mybatis SQL mapper - 			
	//sql 구문에서 limit ?,페이지당 출력 수 설정
	public void setPerPageNum(int perPageNum) {
		if(perPageNum <= 0) {
			this.perPageNum = 10;
			return; 
		}
		this.perPageNum = perPageNum;
	}	
	public int getPerPageNum() {
		return perPageNum;
	}
	
	// limit 시작 값 ( 메서드 처리 ) 계산해서 get만 출력(set 없어도됨)
	public int getPageStart() {
		return (this.page - 1) * this.perPageNum;
	}

	@Override
	public String toString() {
		return "Criteria [page=" + page + ", perPageNum=" + perPageNum + "]";
	}	

}

 

2) BoardDAO.java

public List<BoardVO> listCriteria(Criteria cri) throws Exception;

 

3) BoardDAOImpl.java

@Override // criteria 객체 페이징
public List<BoardVO> listCriteria(Criteria cri) throws Exception {
    return session.selectList(namespace+".listCriteria", cri);
}

 

4) boardMapper.xml

<select id="listCriteria" resultType="BoardVO">
    <![CDATA[
    select * from tbl_board where bno > 0 order by bno desc limit #{pageStart}, #{perPageNum}
    ]]>
</select>

 

5) BoardDAOTest.java

@Test
public void testListCriteria() throws Exception {
    Criteria cri = new Criteria();

    cri.setPage(2); //출력할 페이지
    cri.setPerPageNum(2); //출력할 게시물 수

    logger.info(cri.toString());

    List<BoardVO> list = dao.listCriteria(cri);

    for (BoardVO boardVO : list) { // 향상된 for문 형식
        logger.info("cri test=="+boardVO.getBno() + ":" + boardVO.getTitle());
    }
}

 

6) BoardService.java

public List<BoardVO> listCriteria(Criteria cri) throws Exception;

 

7) BoardServiceImpl.java

@Override
public List<BoardVO> listCriteria(Criteria cri) throws Exception {
    return dao.listCriteria(cri);
}

 

8)  BoardController.java

@RequestMapping(value = "/listCri", method = RequestMethod.GET)
public void listCri(Criteria cri, Model model) throws Exception {
    logger.info("show list Page with Criteria......................");

    model.addAttribute("list", service.listCriteria(cri));
}

 

9) header.jsp

<a href="/board/listCri">[listCri]</a>

 

10) listCri.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<script>
	var result = "${msg}";

	if(result == "register"){ // alert 뜬 후 새로고침하면 없어지므로 다시 뜨진 않음
		alert("작성 완료!");
	}else if(result == "delete"){
		alert("삭제 완료!");
	}else if(result == "modify"){
		alert("수정 완료!");
	}
</script>

<center>
<h3>LIST PAGE</h3>

<table border=1 width=700>
	<tr>
		<th style="width:10px">BNO</th>
		<th>TITLE</th>
		<th>WRITER</th>
		<th>REGDATE</th>
		<th style="width: 40px">VIEWCNT</th>
	</tr>
	
	<c:forEach var="boardVO" items="${list}">
	<tr>
		<td>${boardVO.bno }</td>
		<td><a href="/board/read?bno=${boardVO.bno }">${boardVO.title }</a></td>
		<td>${boardVO.writer }</td>
		<!-- <td>${boardVO.regdate }</td>  --> 
		<td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${boardVO.regdate }"/></td>
		<td>${boardVO.viewcnt }</td>
	</tr>
	</c:forEach>
</table>

<br>

<table border=0 width=700>
	<tr>
		<td align=right><a href="register">[글쓰기]</a></td>
	</tr>
</table>

</center>

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

3. pageMaker --> domain에

    ㄴ> 페이징 블럭 담당

1) PageMaker.java

package org.zerock.domain;

import lombok.Data;

@Data
public class PageMaker {
	private int totalCount; // 총 게시물 수
	private int startPage; // 시작 페이지
	private int endPage; // 끝 페이지
	private boolean prev; // 이전 링크
	private boolean next; // 다음 링크
	private int displayPageNum = 5; //블럭 갯수
	private Criteria cri; // limit 메소드 이용
	
	private void calcData() {
		endPage = (int) (Math.ceil(cri.getPage() / (double) displayPageNum) * displayPageNum);
		//endPage = 현재 페이지 번호 / 블럭 개수 * 블럭 개수
		// Math.ceil --> 0보다 크다면 올림 함 (0.3이라면 1로)
		//현재 페이지가 3 : Math.ceil(3/10) * 10 = 10  
		//현재 페이지가 1 : Math.ceil(1/10) * 10 = 10
		//현재 페이지가 20 : Math.ceil(20/10) * 10 = 20
		//현재 페이지가 21 : Math.ceil(21/10) * 10 = 30	
	
		startPage = (endPage - displayPageNum) + 1;
		//현재 페이지가 21 : startPage = (30 - 10) + 1 = 21 
	
		// 마지막 블럭일 경우 계산 처리
		int tempEndPage = (int) (Math.ceil(totalCount / (double) cri.getPerPageNum()));
		if (endPage > tempEndPage) {
			endPage = tempEndPage;
		}
	
		prev = startPage == 1 ? false : true; //시작 페이지가 1이 아니라면 true
		next = endPage * cri.getPerPageNum() >= totalCount ? false : true;
		//endPage = 10 , perPageNum = 10 , totalCount = 101 이라면 next = true 되어야 한다. 
	}
	
	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	
		//위 메소드 호출
		calcData();

	}
}

 

2) BoardController.java

@RequestMapping(value = "/listPage", method = RequestMethod.GET)
	public void listPage(@ModelAttribute("cri") Criteria cri, Model model) throws Exception {
		logger.info(cri.toString());

		model.addAttribute("list", service.listCriteria(cri)); //현재 페이지 리스트 출력 내용

		PageMaker pageMaker = new PageMaker();

		pageMaker.setCri(cri);

		pageMaker.setTotalCount(131); //임의로 131개로 데이터 입력 테스트

		model.addAttribute("pageMaker", pageMaker); //현재 페이지에 해당하는 페이징 값들

	}

 

3) listPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<script>
	var result = "${msg}";

	if(result == "register"){ // alert 뜬 후 새로고침하면 없어지므로 다시 뜨진 않음
		alert("작성 완료!");
	}else if(result == "delete"){
		alert("삭제 완료!");
	}else if(result == "modify"){
		alert("수정 완료!");
	}
</script>

<center>
<h3>LIST PAGE</h3>

<table border=1 width=700>
	<tr>
		<th style="width:10px">BNO</th>
		<th>TITLE</th>
		<th>WRITER</th>
		<th>REGDATE</th>
		<th style="width: 40px">VIEWCNT</th>
	</tr>
	
	<c:forEach var="boardVO" items="${list}">
	<tr>
		<td>${boardVO.bno }</td>
		<td><a href="/board/readPage?bno=${boardVO.bno }&page=${pageMaker.cri.page}">${boardVO.title }</a></td> <!-- pageMaker.cri.page or cri.page -->
		<td>${boardVO.writer }</td>
		<!-- <td>${boardVO.regdate }</td>  --> 
		<td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${boardVO.regdate }"/></td>
		<td>${boardVO.viewcnt }</td>
	</tr>
	</c:forEach>
</table>

<br>

<table border=0 width=700>
	<tr>
		<td align=right><a href="register">[글쓰기]</a></td>
	</tr>
</table>

<!-- 페이징 추가 -->
<table border=1 width=200 align=center>
	<tr>
		<c:if test="${pageMaker.prev}">
			<td><a href="listPage?page=${pageMaker.startPage - 1 }">&laquo;</a></td>
		</c:if>

		<c:forEach var="idx" begin="${pageMaker.startPage }" end="${pageMaker.endPage }">
			<td>
				<c:if test="${pageMaker.cri.page == idx}"><b></c:if>
				<a href="listPage?page=${idx}">${idx}</a>
				<c:if test="${pageMaker.cri.page == idx}"></b></c:if>
			</td>
		</c:forEach>

		<c:if test="${pageMaker.next && pageMaker.endPage > 0}">
			<td><a href="listPage?page=${pageMaker.endPage +1 }">&raquo;</a></td>
		</c:if>
	</tr>
</table>

</center>

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

4) header.jsp

<a href="/board/listPage">[listPage]</a>

 

perPageNum = 10 , totalCount = 122 , displayPageNum = 10(블럭) 
 ㄴ> 122개를 10개씩 보여준다 총 13페이지 
        < 1~10 > 
        < 11~13 >

. page = 3 일 경우
- startPage = 1 , endPage = 10 , next = true , prev = false //  첫번째 블럭이므로 prev( < )는 false

. page = 10 일 경우
- startPage = 1 , endPage = 10 , next = true , prev = false   //  첫번째 블럭이므로 prev( < )는 false

. page = 11 일 경우
- startPage = 11 , endPage = 20 , next = false , prev = true  //  두번째 블럭이므로 next( > )는 false

 

4.  총게시물수

1) BoardDAO.java

public int countPaging(Criteria cri) throws Exception;

 

2) BoardDAOImpl.java

@Override
public int countPaging(Criteria cri) throws Exception {
    return session.selectOne(namespace+".countPaging", cri);
}

 

3) boardMapper.xml

<select id="countPaging" resultType="int">
    <![CDATA[
    select count(bno) from tbl_board where bno > 0
    ]]>
</select>

 

4) BoardService.java

public int listCountCriteria(Criteria cri) throws Exception;

 

5) BoardServiceImpl.java

@Override
public int listCountCriteria(Criteria cri) throws Exception {
    return dao.countPaging(cri);
}

 

6) BoardController.java --> value="/listPage" 에 추가

//pageMaker.setTotalCount(131);
pageMaker.setTotalCount(service.listCountCriteria(cri)); //총 게시물 수

 

7) readPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<center>
<h3>READ PAGE</h3>

<table border=1 width=570>
	<tr>
		<td width=70>제목</td>
		<td width=500>${boardVO.title }</td>
	</tr>
	<tr>
		<td>내용</td>
		<td>${boardVO.content }</td>
	</tr>
	<tr>
		<td>작성자</td>
		<td>${boardVO.writer }</td>
	</tr>
</table>

<br>

<table border=0 width=570>
	<tr>
		<td width=50%><a href="listPage?&page=${param.page}">[리스트]</a></td>
		<td width=50% align="right">
			<a href="/board/modifyPage?bno=${boardVO.bno }&page=${param.page}">[수정]</a> <!-- pageMaker.cri.page or 주소창에 이미 불러와있으므로 param.page도 가능 -->
			<a href="/board/removePage?bno=${boardVO.bno }">[삭제]</a>
		</td>
	</tr>
</table>


<!-- ajax 이용 -->
<form role="pkt" name="pkt" method="get">
	<input type="hidden" name="bno" value="${boardVO.bno }">
</form>

<button class="btn-modify">수정</button>
<button class="btn-delete">삭제</button>
<button class="btn-list">리스트</button>



</center>

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

8) modifyPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/include/header.jsp" %>

<center>
<h3>MODIFY PAGE</h3>

<form role="pkt" name="pkt" method="post">
<input type="hidden" name="bno" value="${boardVO.bno}">
<input type="hidden" name="page" value="${param.page}">
<table>
	<tr>
		<td>제목</td>
		<td><input name="title" value="${boardVO.title}"></td>
	</tr>
	<tr>
		<td>내용</td>
		<td><textarea name="content" rows="3">${boardVO.content}</textarea></td>
	</tr>
	<tr>
		<td>작성자</td>
		<td><input name="writer" value="${boardVO.writer}" readonly></td>
	</tr>
	<tr>
		<td></td>
		<td><button type="submit">Submit</button></td>
	</tr>
</table>
</form>

</center>

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

5. UriComponentsBuilder 이용

함수처리
주소?변수=값&변수=값
대신 메소드 처리

 

1) BoardDAOTest.java --> 추가

//@Test  
public void testURI() throws Exception {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .path("/board/read") // 경로
        .queryParam("bno", 12) //변수전달
        .queryParam("perPageNum", 10)
        .build();

    //logger.info("/board/read?bno=12&perPageNum=10");
    //logger.info(uriComponents.toString());
}

// UriComponents 클래스는 path나 query에 해당하는 문자열들을 추가해서 원하는 URI를 생성할 때 사용한다.
// 위 코드의 실행 결과는 아래와 같이 동일하게 보여진다.
// INFO : org.zerock.controller.BoardDAOTest - /board/read?bno=12&perPageNum=10
// 원하는 데이터를 계속 추가해서 처리할 수 있고, 필요한 데이터를 설정한다.
// 위의 코드에서 queryParam()의 경우 나중에 GET방식의 ? 뒤에 붙는 데이터가 되는 것을 볼 수 있다.


@Test
public void testURI2() throws Exception {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .path("/{module}/{page}")
        .queryParam("bno", 12)
        .queryParam("perPageNum", 10)
        .build()
        .expand("board", "read") // path 변수에 들어갈 녀석들
        .encode();

    logger.info("/board/read?bno=12&perPageNum=10");
    logger.info(uriComponents.toString());
}
// 위와 같이 미리 필요한 경로를 지정해 두고 {module}와 같은 경로를 'board'로 {page}를 'read'로 변경할 수 있다.

 

2) Pagemaker.java --> 추가

// get방식 - url 주소 변수 값 - 처리 용이하게..
public String makeQuery(int page) {
    UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .queryParam("page", page)
        .queryParam("perPageNum", cri.getPerPageNum())
        .build();

    return uriComponents.toUriString();
}

 

3) listPage.jsp --> 추가

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<script>
	var result = "${msg}";

	if(result == "register"){ // alert 뜬 후 새로고침하면 없어지므로 다시 뜨진 않음
		alert("작성 완료!");
	}else if(result == "delete"){
		alert("삭제 완료!");
	}else if(result == "modify"){
		alert("수정 완료!");
	}
</script>

<center>
<h3>LIST PAGE</h3>

<table border=0 width=700>
	<tr>
		<td>Total : ${pageMaker.totalCount }</td>
	</tr>
</table>

<table border=1 width=700>
	<tr>
		<th style="width:10px">BNO</th>
		<th>TITLE</th>
		<th>WRITER</th>
		<th>REGDATE</th>
		<th style="width: 40px">VIEWCNT</th>
	</tr>
	
	<c:forEach var="boardVO" items="${list}">
	<tr>
		<td>${boardVO.bno }</td>
		<td> <!-- pageMaker.cri.page or cri.page -->
			<%-- <a href="/board/readPage?bno=${boardVO.bno }&page=${pageMaker.cri.page}">${boardVO.title }</a> --%>
			<a href="/board/readPage${pageMaker.makeQuery(pageMaker.cri.page)}&bno=${boardVO.bno }">${boardVO.title }</a> <!-- UriComponentsBuilder 이용한다면  -->
		</td> 
		<td>${boardVO.writer }</td>
		<!-- <td>${boardVO.regdate }</td>  --> 
		<td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${boardVO.regdate }"/></td>
		<td>${boardVO.viewcnt }</td>
	</tr>
	</c:forEach>
</table>

<br>

<table border=0 width=700>
	<tr>
		<td align=right><a href="register">[글쓰기]</a></td>
	</tr>
</table>

<!-- 페이징 추가 -->
<table border=1 align=center>
	<tr>
		<c:if test="${pageMaker.prev}">
			<td>
				<%-- <a href="listPage?page=${pageMaker.startPage - 1 }">&laquo;</a> --%>
				<a href="listPage${pageMaker.makeQuery(pageMaker.startPage - 1)}">&laquo;</a>
			</td>
		</c:if>

		<c:forEach var="idx" begin="${pageMaker.startPage }" end="${pageMaker.endPage }">
			<td>
				<c:if test="${pageMaker.cri.page == idx}"><b></c:if>
				<a href="listPage${pageMaker.makeQuery(idx)}">${idx}</a> <!-- <a href="listPage?page=${idx}">${idx}</a> -->
				<c:if test="${pageMaker.cri.page == idx}"></b></c:if>
			</td>
		</c:forEach>

		<c:if test="${pageMaker.next && pageMaker.endPage > 0}">
			<td>
				<%-- <a href="listPage?page=${pageMaker.endPage +1 }">&raquo;</a> --%>
				<a href="listPage${pageMaker.makeQuery(pageMaker.endPage +1)}">&raquo;</a>
			</td>
		</c:if>
	</tr>
</table>

</center>

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

4) BoardController.java --> 추가

Criteria cri 로 해도 됨 (cri 로 사용 안할 거라면!! )

 ㄴ> readPage.jsp 에서 <a href="/board/modifyPage${pageMaker.makeQuery(cri.page)}&bno=${boardVO.bno }"> 와 같이 pageMaker 없애고 cri.page로 사용하면 됨

@RequestMapping(value = "/readPage", method = RequestMethod.GET) // pageMaker 사용하기 위해 cri 추가
public void readPage(@RequestParam("bno") int bno, @ModelAttribute("cri") Criteria cri, Model model) throws Exception {
    logger.info("readPage get ...........");

    PageMaker pageMaker = new PageMaker();
    pageMaker.setCri(cri);

    model.addAttribute("pageMaker", pageMaker); // forward
    model.addAttribute(service.read(bno));
}

 

5) readPage.jsp --> 추가

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<center>
<h3>READ PAGE</h3>

<table border=1 width=570>
	<tr>
		<td width=70>제목</td>
		<td width=500>${boardVO.title }</td>
	</tr>
	<tr>
		<td>내용</td>
		<td>${boardVO.content }</td>
	</tr>
	<tr>
		<td>작성자</td>
		<td>${boardVO.writer }</td>
	</tr>
</table>

<br>

<table border=0 width=570>
	<tr>
		<td width=50%>
			<%-- <a href="listPage?&page=${param.page}">[리스트]</a> --%>
			<a href="listPage${pageMaker.makeQuery(pageMaker.cri.page)}">[리스트]</a>
		</td>
		<td width=50% align="right">
			<%-- <a href="/board/modifyPage?bno=${boardVO.bno }&page=${param.page}">[수정]</a> --%> <!-- pageMaker.cri.page or 주소창에 이미 불러와있으므로 param.page도 가능 -->
			<a href="/board/modifyPage${pageMaker.makeQuery(pageMaker.cri.page)}&bno=${boardVO.bno }">수정</a>
			<a href="/board/removePage?bno=${boardVO.bno }">[삭제]</a>
		</td>
	</tr>
</table>


<!-- ajax 이용 -->
<form role="pkt" name="pkt" method="get">
	<input type="hidden" name="bno" value="${boardVO.bno }">
</form>

<button class="btn-modify">수정</button>
<button class="btn-delete">삭제</button>
<button class="btn-list">리스트</button>



</center>

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

 

 

 

'JAVA > spring' 카테고리의 다른 글

스프링 member 구현  (0) 2023.05.03
스프링 Board 구현_넘버링, 검색  (0) 2023.05.03
스프링 Board 구현  (0) 2023.04.28
스프링 페이지 이동(변수 전달)  (0) 2023.04.28
스프링 프로젝트 생성  (0) 2023.04.27
profile

데일리로그C:

@망밍

포스팅이 도움됐다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...