25. 스프링 게시판 만들기/ 첨부파일 업로드, 다운로드(2)
안녕하세요
이전 게시글에서는 첨부파일을 업로드하는 방법에대해 작성하였는데요.
이번엔 첨부파일을 조회하는 방법에대해 작성하겠습니다.
1. boardMapper.xml 작성
첨부파일을 조회하기위해 게시글의 번호를 파라미터로 받습니다.
#{BNO}에 471이 들어가면 471번 글의 첨부된 파일 목록들이 나오겠지요.
ROUND를 이용하여 1024로 파일크기를 나누어 1024당 1로 계산합니다.
<!-- 첨부파일 조회 -->
<select id="selectFileList" parameterType="int" resultType="hashMap">
SELECT FILE_NO,
ORG_FILE_NAME,
ROUND(FILE_SIZE/1024,1) AS FILE_SIZE
FROM MP_FILE
WHERE BNO = #{BNO}
AND DEL_GB = 'N'
</select>
2. BoardDAO 작성
첨부파일 조회를 위한 코드를 작성합니다. 파라미터는 bno로 보내주어야겠지요.
타입을 List형식으로 한 이유는 나중에 여러개의 파일을 등록할 수 있도록 하기 위함입니다.
BoardDAO
// 첨부파일 조회
public List<Map<String, Object>> selectFileList(int bno) throws Exception;
BoardDAOImpl
// 첨부파일 조회
@Override
public List<Map<String, Object>> selectFileList(int bno) throws Exception {
// TODO Auto-generated method stub
return sqlSession.selectList("boardMapper.selectFileList", bno);
}
3. BoardService 작성
BoardService와 Impl도 코드를 작성해줍니다.
BoardService
// 첨부파일 조회
public List<Map<String, Object>> selectFileList(int bno) throws Exception;
BoardServiceImpl
// 첨부파일 조회
@Override
public List<Map<String, Object>> selectFileList(int bno) throws Exception {
// TODO Auto-generated method stub
return dao.selectFileList(bno);
}
4. BoardController 작성
selectFileList에 파라미터값(게시글 조회한 번호)을 넣어주고 Map타입의 List타입 fileList에 넣어줍니다.
model.addAttribute를 이용하여 fileList를 file이라는 이름으로 jsp에 값을 보낼준비를 합니다.
// 게시판 조회
@RequestMapping(value = "/readView", method = RequestMethod.GET)
public String read(BoardVO boardVO, @ModelAttribute("scri") SearchCriteria scri, Model model) throws Exception {
logger.info("read");
model.addAttribute("read", service.read(boardVO.getBno()));
model.addAttribute("scri", scri);
List<ReplyVO> replyList = replyService.readReply(boardVO.getBno());
model.addAttribute("replyList", replyList);
List<Map<String, Object>> fileList = service.selectFileList(boardVO.getBno());
model.addAttribute("file", fileList);
return "board/readView";
}
5. readView 작성
파일 목록을 만들어줍니다.
forEach문을 이용하여 파일을 모두 가져와줍니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
<head>
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<title>게시판</title>
</head>
<script type="text/javascript">
$(document).ready(function(){
var formObj = $("form[name='readForm']");
// 수정
$(".update_btn").on("click", function(){
formObj.attr("action", "/board/updateView");
formObj.attr("method", "get");
formObj.submit();
})
// 삭제
$(".delete_btn").on("click", function(){
var deleteYN = confirm("삭제하시겠습니까?");
if(deleteYN == true){
formObj.attr("action", "/board/delete");
formObj.attr("method", "post");
formObj.submit();
}
})
// 목록
$(".list_btn").on("click", function(){
location.href = "/board/list?page=${scri.page}"
+"&perPageNum=${scri.perPageNum}"
+"&searchType=${scri.searchType}&keyword=${scri.keyword}";
})
$(".replyWriteBtn").on("click", function(){
var formObj = $("form[name='replyForm']");
formObj.attr("action", "/board/replyWrite");
formObj.submit();
});
//댓글 수정 View
$(".replyUpdateBtn").on("click", function(){
location.href = "/board/replyUpdateView?bno=${read.bno}"
+ "&page=${scri.page}"
+ "&perPageNum=${scri.perPageNum}"
+ "&searchType=${scri.searchType}"
+ "&keyword=${scri.keyword}"
+ "&rno="+$(this).attr("data-rno");
});
//댓글 삭제 View
$(".replyDeleteBtn").on("click", function(){
location.href = "/board/replyDeleteView?bno=${read.bno}"
+ "&page=${scri.page}"
+ "&perPageNum=${scri.perPageNum}"
+ "&searchType=${scri.searchType}"
+ "&keyword=${scri.keyword}"
+ "&rno="+$(this).attr("data-rno");
});
})
</script>
<body>
<div class="container">
<header>
<h1> 게시판</h1>
</header>
<hr />
<div>
<%@include file="nav.jsp" %>
</div>
<section id="container">
<form name="readForm" role="form" method="post">
<input type="hidden" id="bno" name="bno" value="${read.bno}" />
<input type="hidden" id="page" name="page" value="${scri.page}">
<input type="hidden" id="perPageNum" name="perPageNum" value="${scri.perPageNum}">
<input type="hidden" id="searchType" name="searchType" value="${scri.searchType}">
<input type="hidden" id="keyword" name="keyword" value="${scri.keyword}">
<input type="hidden" id="FILE_NO" name="FILE_NO" value="">
</form>
<div class="form-group">
<label for="title" class="col-sm-2 control-label">제목</label>
<input type="text" id="title" name="title" class="form-control" value="${read.title}" readonly="readonly" />
</div>
<div class="form-group">
<label for="content" class="col-sm-2 control-label">내용</label>
<textarea id="content" name="content" class="form-control" readonly="readonly"><c:out value="${read.content}" /></textarea>
</div>
<div class="form-group">
<label for="writer" class="col-sm-2 control-label">작성자</label>
<input type="text" id="writer" name="writer" class="form-control" value="${read.writer}" readonly="readonly"/>
</div>
<div class="form-group">
<label for="regdate" class="col-sm-2 control-label">작성날짜</label>
<fmt:formatDate value="${read.regdate}" pattern="yyyy-MM-dd" />
</div>
<hr>
<span>파일 목록</span>
<div class="form-group" style="border: 1px solid #dbdbdb;">
<c:forEach var="file" items="${file}">
<a href="#" onclick="fn_fileDown('${file.FILE_NO}'); return false;">${file.ORG_FILE_NAME}</a>(${file.FILE_SIZE}kb)<br>
</c:forEach>
</div>
<hr>
<div>
<button type="button" class="update_btn btn btn-warning">수정</button>
<button type="button" class="delete_btn btn btn-danger">삭제</button>
<button type="button" class="list_btn btn btn-primary">목록</button>
</div>
<!-- 댓글 -->
<div id="reply">
<ol class="replyList">
<c:forEach items="${replyList}" var="replyList">
<li>
<p>
작성자 : ${replyList.writer}<br />
작성 날짜 : <fmt:formatDate value="${replyList.regdate}" pattern="yyyy-MM-dd" />
</p>
<p>${replyList.content}</p>
<div>
<button type="button" class="replyUpdateBtn btn btn-warning" data-rno="${replyList.rno}">수정</button>
<button type="button" class="replyDeleteBtn btn btn-danger" data-rno="${replyList.rno}">삭제</button>
</div>
</li>
</c:forEach>
</ol>
</div>
<form name="replyForm" method="post" class="form-horizontal">
<input type="hidden" id="bno" name="bno" value="${read.bno}" />
<input type="hidden" id="page" name="page" value="${scri.page}">
<input type="hidden" id="perPageNum" name="perPageNum" value="${scri.perPageNum}">
<input type="hidden" id="searchType" name="searchType" value="${scri.searchType}">
<input type="hidden" id="keyword" name="keyword" value="${scri.keyword}">
<div class="form-group">
<label for="writer" class="col-sm-2 control-label">댓글 작성자</label>
<div class="col-sm-10">
<input type="text" id="writer" name="writer" class="form-control" />
</div>
</div>
<div class="form-group">
<label for="content" class="col-sm-2 control-label">댓글 내용</label>
<div class="col-sm-10">
<input type="text" id="content" name="content" class="form-control"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="replyWriteBtn btn btn-success">작성</button>
</div>
</div>
</form>
</section>
<hr />
</div>
</body>
</html>
6. 실행 테스트
다음 글에서는 다운로드에 관해 작성하겠습니다..