<body>
<header>
//1
<input type="hidden" name="searchCondition" value="${searchCondition }">
<input type="hidden" name="searchValue" value="${searchValue}">
<jsp:include page="../home.jsp"/>
</header>
<h1 align="center">게시글 목록</h1>
<br>
<br>
<table align="center" border="1">
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>날짜</th>
<th>조회수</th>
<th>첨부파일</th>
</tr>
<!-- 게시물 리스트 출력시 리스트 반환값이 있을때/없을때 if문 -->
<!-- 반환값 있을때 -->
<c:if test="${!empty bList }">
<c:forEach items="${bList }" var="board" varStatus="i">
<tr>
<td>${i.count }</td>
//2
<c:if test="${searchValue eq null }">
<td><a href="/board/detail.kh?boardNo=${board.boardNo }&page=${pageNow }">${board.boardTitle }</td>
</c:if>
<c:if test="${searchValue ne null }">
<td><a
href="/board/detail.kh?boardNo=${board.boardNo }&searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }">${board.boardTitle }</td>
</c:if>
<td>${board.boardWirter }</td>
<td>${board.bCreateDate }</td>
<td>${board.boardCount }</td>
<c:if test="${!empty board.boardFile }">
<td>O</td>
</c:if>
<c:if test="${empty board.boardFile }">
<td>X</td>
</c:if>
</tr>
</c:forEach>
</c:if>
<!-- 반환값 없을때 -->
<c:if test="${empty bList }">
<tr>
<td colspan="6" rowspan = "2" align="center">데이터가 존재하지 않습니다</td>
</tr>
</c:if>
<!-- 리스트 if문 종료 -->
<!-- 검색/ 일반 페이징 c:if 시작 -->
<!-- 일반 페이징 시작 -->
<c:if test="${searchValue eq null }">
<tr align="center" height="20">
<td colspan="6">
<!-- startNavi가 1일이 아닐때만 출력 --> <c:if
test="${startNavi ne 1 && startNavi > 0}">
<a href="/board/${urlVal }.kh?page=${startNavi-1 }">이전</a>
</c:if> <!-- p는 기준을 삼을 임시변수 startNavi부터 시작해 endNavi까지 출력한다 --> <c:forEach
var="p" begin="${startNavi }" end="${endNavi }">
<c:if test="${pageNow == p }">
<b>${p }</b>
</c:if>
<c:if test="${pageNow ne p}">
<a href="/board/${urlVal }.kh?page=${p }">${p }</a>
</c:if>
</c:forEach> <!-- endNavi가 maxPage와 같지 않을때만 출력 --> <c:if
test="${endNavi < maxPage }">
<a href="/board/${urlVal }.kh?page=${endNavi+1 }">다음</a>
</c:if>
</td>
</tr>
</c:if>
<!-- 검색 페이징 시작 -->
<c:if test="${searchValue ne null }">
<tr align="center" height="20">
<td colspan="6">
<!-- startNavi가 1일이 아닐때만 출력 --> <c:if
test="${startNavi ne 1 && startNavi > 0}">
<a
href="/board/${urlVal }.kh?searchCondition=${searchCondition }&searchValue=${searchValue}&page=${startNavi-1 }">이전</a>
</c:if> <!-- p는 기준을 삼을 임시변수 startNavi부터 시작해 endNavi까지 출력한다 --> <c:forEach
var="p" begin="${startNavi }" end="${endNavi }">
<c:if test="${pageNow == p}">
<b>${p }</b>
</c:if>
<c:if test="${pageNow ne p}">
<a
href="/board/${urlVal }.kh?searchCondition=${searchCondition }&searchValue=${searchValue}&page=${p }">${p }</a>
</c:if>
</c:forEach> <!-- endNavi가 maxPage와 같지 않을때만 출력 --> <c:if
test="${endNavi < maxPage }">
<a
href="/board/${urlVal }.kh?searchCondition=${searchCondition }&searchValue=${searchValue}&page=${endNavi+1 }">다음</a>
</c:if>
</td>
</tr>
</c:if>
<!-- 일반/ 검색용 페이징 종료 -->
<tr>
<td colspan="4" align="center">
<form action="/board/search.kh" method="get">
<select name="searchCondition">
<option value="all" <c:if test="${searchCondition eq 'all' }"> selected </c:if>>전체</option>
<option value="writer" <c:if test="${searchCondition eq 'writer' }"> selected </c:if> >작성자</option>
<option value="title" <c:if test="${searchCondition eq 'title' }"> selected </c:if> >제목</option>
<option value="contents" <c:if test="${searchCondition eq 'contents' }"> selected </c:if> >내용</option>
</select>
<input type="text" size="25" name="searchValue" required="required" value="${searchValue }">
<input type="submit" value="검색">
</form>
</td>
<td colspan="2" align="center">
<button onclick="location.href='/board/writeView.kh';">글쓰기</button>
</td>
</tr>
</table>
</body>
@RequestMapping(value="/board/list.kh", method =RequestMethod.GET)
public ModelAndView boardList(ModelAndView mv,
@RequestParam(value="page", required=false) Integer page,
HttpSession session) {
//@RequestParam(value="page", required=false)의 값은 page이지만
// required=false 필수값은 아니라는 뜻
int currentPage = (page != null) ? page: 1;
//현재 페이지
//만약 page값이 없으면 기본형 1로 출력할것, 아니면 받아온 page의 값을 준다.
//삼항연상자 사용
int totalCount = bService.getTotalCount("", "");
int boardLimit = 10; //한 화면에 출력할 게시물 수
int naviLimit = 5; //한 화면에 출력할 게시판 페이지 수
int maxPage; //게시판의 총 페이지 수
int startNavi; //한 화면에 출력되는 게시판 페이지의 처음 수
int endNavi;//한 화면에 출력되는 게시판 페이지의 마지막 수
maxPage =(int)((double)totalCount/boardLimit+0.9);
startNavi = ((int)((double)currentPage/naviLimit+0.9)-1)*naviLimit+1;
endNavi=startNavi+naviLimit-1;
//endNavi가 maxNavi보다 커지는 오류방지
if(maxPage<endNavi) {
endNavi = maxPage;
}
List<Board> bList = bService.printAllBoard(currentPage, boardLimit);
if(!bList.isEmpty()) {
mv.addObject("urlVal","list");
mv.addObject("startNavi",startNavi);
mv.addObject("endNavi", endNavi);
mv.addObject("maxPage", maxPage);
mv.addObject("currentPage", currentPage);
mv.addObject("bList", bList);
}
//1
mv.addObject("pageNow", currentPage);
mv.setViewName("/board/listView");
return mv;
}
/**
* 게시물 검색
* @param mv
* @param searchCondition
* @param searchValue
* @return
*/
@RequestMapping (value="/board/search.kh", method = RequestMethod.GET)
public ModelAndView boardSearchList(ModelAndView mv,
@RequestParam("searchCondition") String searchCondition,
@RequestParam(value="page", required=false) Integer page, //페이징을 위한 매개변수
@RequestParam("searchValue") String searchValue,
HttpSession session) {
try {
/////////////////////////////////페이징시작//////////////////////////////
int currentPage = (page != null) ? page: 1;
int boardLimit = 10; //한 화면에 출력할 게시물 수
/////페이징용////
List<Board> bList = bService.printAllByValue(searchCondition, searchValue, currentPage, boardLimit);
if(!bList.isEmpty()) {
mv.addObject("bList",bList);
}else {
mv.addObject("bList",null);
}
/////페이징용////
int totalCount = bService.getTotalCount(searchCondition, searchValue);
int naviLimit = 5; //한 화면에 출력할 게시판 페이지 수
int maxPage; //게시판의 총 페이지 수
int startNavi; //한 화면에 출력되는 게시판 페이지의 처음 수
int endNavi;//한 화면에 출력되는 게시판 페이지의 마지막 수
maxPage =(int)((double)totalCount/boardLimit+0.9);
startNavi = ((int)((double)currentPage/naviLimit+0.9)-1)*naviLimit+1;
endNavi=startNavi+naviLimit-1;
//endNavi가 maxNavi보다 커지는 오류방지
if(maxPage<endNavi) {
endNavi = maxPage;
}
mv.addObject("urlVal","search");
mv.addObject("startNavi",startNavi);
mv.addObject("endNavi", endNavi);
mv.addObject("maxPage", maxPage);
////////////////////////////////페이징종료///////////////////////////////////
//1
mv.addObject("pageNow", currentPage);
mv.addObject("searchValue",searchValue);
mv.addObject("searchCondition",searchCondition);
mv.setViewName("board/listView");
}catch (Exception e) {
mv.addObject("msg",e.getMessage()).setViewName("/common/errorPage");
}
return mv;
}
아까와 똑같이 현재 페이지를 pageNow라는 이름으로 저장했다.
<c:if test="${searchValue ne null }">
<td><a
href="/board/detail.kh?boardNo=${board.boardNo }&searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }">${board.boardTitle }</td>
</c:if>
/**
* 게시물 상세보기
* @param mv
* @param boardNo
* @param session
* @return
*/
@RequestMapping(value="/board/detail.kh", method = RequestMethod.GET)
public ModelAndView boardDetailView(ModelAndView mv,
@RequestParam ("boardNo") Integer boardNo,
//1
@RequestParam(value="searchCondition", required=false) String searchCondition,
@RequestParam(value="searchValue", required=false) String searchValue,
@RequestParam(value="page", required=false) String pageNow,
HttpSession session) {
if(boardNo != null) {
Board board = bService.printOneVyNo(boardNo);
session.setAttribute("boardNo", boardNo); // 세션에 boardNo가 추가된다, 현재 가지고 있는 세션은 유지된다.
try {
//2
mv.addObject("board", board);
mv.addObject("searchCondition", searchCondition);
mv.addObject("searchValue", searchValue);
mv.addObject("pageNow", pageNow);
mv.setViewName("/board/detail");
}catch (Exception e) {
mv.addObject("mgs",e.getMessage());
mv.setViewName("/common/errorPage");
}
}
else {
mv.addObject("msg","게시물 선택 오류");
mv.setViewName("/common/errorPage");
}
return mv;
}
<body>
<header>
<jsp:include page="../home.jsp" />
</header>
<table align="center" border="1">
<tr>
<td>제목</td>
<td>${board.boardTitle }</td>
</tr>
<tr>
<td>작성자</td>
<td>${board.boardWirter }</td>
</tr>
<tr>
<td>작성일</td>
<td>${board.bCreateDate }</td>
</tr>
<tr>
<td>내용</td>
<td>${board.boardContents } <br> <c:if
test="${board.boardRename ne null}">
<img alt="본문이미지"
src="/resources/buploadFiles/${board.boardRename }">
</c:if>
</td>
</tr>
<tr>
<td colspan="2">
<!--검색/일반의 경우 목록주소 --> <!-- 일반으로 상세 진입시 목록 -->
//1
<c:if test="${empty searchValue }">
<input type="button" value="수정"
onclick="location.href='/board/modifyView.kh?boardNo=${board.boardNo}&page=${pageNow }';">
<button type="button"
onclick="location.href='/board/list.kh?page=${pageNow }';">목록</button>
</c:if> <!-- 검색 으로 상세 진입시 --> <c:if test="${searchValue ne null }">
<input type="button" value="수정"
onclick="location.href='/board/modifyView.kh?boardNo=${board.boardNo}&searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }';">
<button type="button"
onclick="location.href='/board/search.kh?searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }';">목록</button>
</c:if> <!-- 목록주소 태그 종료 -->
<button type="button" onclick="remove()">삭제</button>
</td>
</tr>
</table>
<!-- 댓글 목록 -->
<form action="/board/addReply.kh" method="post">
<table align="center" width="500" border="1">
<tr>
<td>
<textarea rows="3" cols="55"></textarea>
</td>
<td>
<button>등록하기</button>
</td>
</tr>
</table>
</form>
</form>
<script>
function remove() {
event.preventDefault(); // 하이퍼링크 이동방지
if (window.confirm("게시물을 삭제하시겠습니까?")) {
location.href = '/board/remove.kh?page=${pageNow}';
}
}
</script>
c:if문을 활용해 검색키워드를 받았을때와 받지 않았을때 목록과 수정으로 가는 주소를 다르게 하였다.
<c:if test="${empty searchValue }">
<input type="button" value="수정"
onclick="location.href='/board/modifyView.kh?boardNo=${board.boardNo}&page=${pageNow }';">
<button type="button"
onclick="location.href='/board/list.kh?page=${pageNow }';">목록</button>
</c:if>
<!-- 검색 으로 상세 진입시 -->
<c:if test="${searchValue ne null }">
<input type="button" value="수정"
onclick="location.href='/board/modifyView.kh?boardNo=${board.boardNo}&searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }';">
<button type="button"
onclick="location.href='/board/search.kh?searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }';">목록</button>
</c:if>
@RequestMapping(value="/board/modifyView.kh", method = RequestMethod.GET)
public ModelAndView boardModifyView(ModelAndView mv,
//1
@RequestParam("boardNo") Integer boardNo,
@RequestParam(value="searchCondition", required = false) String searchCondition,
@RequestParam(value="searchValue", required = false) String searchValue,
@RequestParam(value="page", required = false) String pageNow
){
try {
Board board = bService.printOneVyNo(boardNo);
if(board!=null){
//2
mv.addObject("board",board);
mv.addObject("searchValue",searchValue);
mv.addObject("searchCondition",searchCondition);
mv.addObject("pageNow",pageNow);
mv.setViewName("board/modifyForm");
}
}
catch (Exception e) {
e.printStackTrace();
mv.addObject("mgs",e.getMessage());
mv.setViewName("/common/errorPage");
}
return mv;
}
<header>
<jsp:include page="../home.jsp"/>
</header>
<h1 align="center">${board.boardNo }번 게시물 수정하기</h1>
<br>
<br>
<!-- enctype을 이용해 파일을 전송한다 오타조심!!!!-->
//1
<form action="/board/modify.kh" method="post" enctype="multipart/form-data">
<input type="hidden" name="boardNo" value="${board.boardNo }" readonly>
<input type="hidden" name="boardRename" value="${board.boardRename }">
<input type="hidden" name="boardFile" value="${board.boardFile }">
<input type="hidden" name="boardFildpath" value="${board.boardFildpath }">
<input type="hidden" name="searchValue" value="${searchValue }">
<input type="hidden" name="searchCondition" value="${searchCondition }">
<input type="hidden" name="page" value="${pageNow }">
<table align="center" border="1">
<tr>
<td>제목</td>
<td><input type="text" name="boardTitle" value="${board.boardTitle }" required="required"></td>
</tr>
<tr>
<td>작성자</td>
<td><input type="text" name="boardWirter" value="${board.boardWirter }" readonly="readonly"></td>
</tr>
<tr>
<td>내용</td>
<td><textarea id="summernote" name="boardContents"
style="resize: none; width: 500px; height: 100%;" required="required"> ${board.boardContents }</textarea></td>
</tr>
<tr>
<td>첨부파일</td>
<td><input type="file" name="reloadFile">
<a href="#"> ${board.boardFile }</a>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="등록"> <input
type="reset" value="취소">
<a href="/board/list.kh">목록으로</a>
<a href="javascript:history.go(-1);">이전페이지로</a>
</td>
</tr>
</table>
</form>
<script>
$('#summernote').summernote({
height : 300, // set editor height
minHeight : null, // set minimum height of editor
maxHeight : null, // set maximum height of editor
focus : true, // set focus to editable area after initializing summernote
});
$('[aria-label="Picture"]').css('display','none');
</script>
</body>
/**
* 게시글 수정
* @param mv
* @param board
* @return
*/
@RequestMapping (value="/board/modify.kh", method = RequestMethod.POST)
public ModelAndView modifyBoard(ModelAndView mv,
@ModelAttribute Board board,
@RequestParam(value="reloadFile", required=false) MultipartFile reloadFile,
@RequestParam(value="searchCondition", required = false) String searchCondition,
@RequestParam(value="searchValue", required = false) String searchValue,
@RequestParam(value="page", required = false) String pageNow,
HttpServletRequest request) {
try {
String boardFilename = reloadFile.getOriginalFilename();
if(reloadFile != null && !boardFilename.equals(""))//새로 파일을 올렸을때, 이름이 없는 파일이 있을 경우를 생각해 null체크 2번함
{//수정 할경우 대체/ 삭제 후 등록/ 대체는 어려워서 삭제후 등록으로 한다
String root = request.getSession().getServletContext().getRealPath("resources");// 저장된 파일의 경로를 가져온다.
String savedPath = root + "\\buploadFiles"; //가져온 경로에 업로드 파일이 들어있는 폴더의 경로까지 더해줌
System.out.println(board.getBoardRename());
File file = new File(savedPath+"\\"+board.getBoardRename()); //이미 저장한 파일의 이름을 가져와야 한다.
if(file.exists()) { //지정한 파일이 있는지 없는지 체크
file.delete(); //있으면 삭제
}
//////////여기부터 파일 재 업로드/////////////////////
//파일 이름으로 업로드하면 파일이름이 겹치면 파일이 겹쳐서 사라진다.
//고유한 rename으로 변경해주어야 한다.
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String boardRename = sdf.format(new Date(System.currentTimeMillis()))+"."+boardFilename.substring(boardFilename.lastIndexOf(".")+1);
reloadFile.transferTo(new File(savedPath + "\\" + boardRename));
board.setBoardFile(boardFilename);
board.setBoardRename(boardRename);
board.setBoardFildpath(savedPath + "\\" + boardRename);
}
String eValue =URLEncoder.encode(searchValue, "UTF-8");
int result = bService.modifyBoardOneByNo(board);
//1
if(searchValue.equals("") || searchValue.isEmpty()) {
mv.setViewName("redirect:/board/detail.kh?boardNo="+board.getBoardNo()+"&page="+pageNow);}
else{
mv.setViewName("redirect:/board/detail.kh?boardNo="+board.getBoardNo()+"&searchCondition="+searchCondition+"&searchValue="+eValue+"&page="+pageNow);
}
}catch (Exception e) {
mv.addObject("mgs",e.getMessage());
mv.setViewName("/common/errorPage");
}
return mv;
}
/**
* 게시물 상세보기
* @param mv
* @param boardNo
* @param session
* @return
*/
@RequestMapping(value="/board/detail.kh", method = RequestMethod.GET)
public ModelAndView boardDetailView(ModelAndView mv,
//1
@RequestParam ("boardNo") Integer boardNo,
@RequestParam(value="searchCondition", required=false) String searchCondition,
@RequestParam(value="searchValue", required=false) String searchValue,
@RequestParam(value="page", required=false) String pageNow,
HttpSession session) {
if(boardNo != null) {
Board board = bService.printOneVyNo(boardNo);
session.setAttribute("boardNo", boardNo); // 세션에 boardNo가 추가된다, 현재 가지고 있는 세션은 유지된다.
try {
//2
mv.addObject("board", board);
mv.addObject("searchCondition", searchCondition);
mv.addObject("searchValue", searchValue);
mv.addObject("pageNow", pageNow);
mv.setViewName("/board/detail");
}catch (Exception e) {
mv.addObject("mgs",e.getMessage());
mv.setViewName("/common/errorPage");
}
}
else {
mv.addObject("msg","게시물 선택 오류");
mv.setViewName("/common/errorPage");
}
return mv;
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${board.boardTitle }</title>
</head>
<body>
<header>
<jsp:include page="../home.jsp" />
</header>
<table align="center" border="1">
<tr>
<td>제목</td>
<td>${board.boardTitle }</td>
</tr>
<tr>
<td>작성자</td>
<td>${board.boardWirter }</td>
</tr>
<tr>
<td>작성일</td>
<td>${board.bCreateDate }</td>
</tr>
<tr>
<td>내용</td>
<td>${board.boardContents } <br> <c:if
test="${board.boardRename ne null}">
<img alt="본문이미지"
src="/resources/buploadFiles/${board.boardRename }">
</c:if>
</td>
</tr>
<tr>
//1
<td colspan="2">
<!--검색/일반의 경우 목록주소 --> <!-- 일반으로 상세 진입시 목록 -->
<c:if test="${empty searchValue }">
<input type="button" value="수정"
onclick="location.href='/board/modifyView.kh?boardNo=${board.boardNo}&page=${pageNow }';">
<button type="button"
onclick="location.href='/board/list.kh?page=${pageNow }';">목록</button>
</c:if> <!-- 검색 으로 상세 진입시 --> <c:if test="${searchValue ne null }">
<input type="button" value="수정"
onclick="location.href='/board/modifyView.kh?boardNo=${board.boardNo}&searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }';">
<button type="button"
onclick="location.href='/board/search.kh?searchCondition=${searchCondition }&searchValue=${searchValue}&page=${pageNow }';">목록</button>
</c:if> <!-- 목록주소 태그 종료 -->
<button type="button" onclick="remove()">삭제</button>
</td>
</tr>
</table>
<!-- 댓글 목록 -->
<form action="/board/addReply.kh" method="post">
<table align="center" width="500" border="1">
<tr>
<td>
<textarea rows="3" cols="55"></textarea>
</td>
<td>
<button>등록하기</button>
</td>
</tr>
</table>
</form>
</form>
<script>
function remove() {
event.preventDefault(); // 하이퍼링크 이동방지
if (window.confirm("게시물을 삭제하시겠습니까?")) {
location.href = '/board/remove.kh?page=${pageNow}';
}
}
</script>
</body>
</html>