today_is
[ jsp 프로젝트 ] 게시글 작성 (+ FileUtil 을 이용한 이미지 업로드 / 페이징) 본문
게시글 작성 - write.jsp
: 게시글 작성은 로그인이 되어있는 상태에서만 가능
작성자가 not null 이기 때문
작성자는 hidden 으로 보낸다
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<c:if test="${empty login }">
<script>
alert('먼저 로그인 후에 작성 가능합니다')
history.go(-1)
</script>
</c:if>
<div class="write">
<h3>글 쓰기</h3>
<form action="write-action.jsp" method="POST" enctype="multipart/form-data">
<p><input type="text" name="title" placeholder="제목"></p>
<p>
<textarea name="content" placeholder="내용" rows="5" cols="30" required></textarea>
</p>
<p><input type="file" name="uploadFile"></p>
<p>
<label><input type="radio" name="category" value="관광">관광</label>
<label><input type="radio" name="category" value="맛집">맛집</label>
</p>
<p><input type="submit" value="글 작성"></p>
<input type="hidden" name="writer" value="${login.userid }">
</form>
</div>
</body>
</html>
게시글 생성처리 - write-action.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<c:set var="dto" value="${fileUtil.getDTO(pageContext.request) }" />
<c:set var="row" value="${boardDAO.insert(dto) }" />
<script>
const row = '${row}'
if(row != 0) {
alert('작성 성공')
location.href = '${cpath}'
}
else {
alert('작성 실패')
history.go(-1)
}
</script>
</body>
</html>
FileUtil
: 이미지 업로드를 담당
C드라이브에 upload 파일을 저장할 디렉토리로 지정
package board;
import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.oreilly.servlet.multipart.FileRenamePolicy;
public class FileUtil {
private static FileUtil instance = new FileUtil();
public static FileUtil getInstance() {
return instance;
}
private FileUtil() {}
private final String saveDirectory = "C:\\upload";
private final int maxPostSize = 1024 * 1024 * 50;
private final String encoding = "UTF-8";
private final FileRenamePolicy policy = new DefaultFileRenamePolicy();
public BoardDTO getDTO(HttpServletRequest request) throws IOException {
BoardDTO dto = new BoardDTO();
MultipartRequest mpRequest = new MultipartRequest(
request, saveDirectory, maxPostSize, encoding, policy);
File uploadFile = mpRequest.getFile("uploadFile");
if (uploadFile != null) {
dto.setImage(uploadFile.getName());
}
dto.setIdx(Integer.parseInt(mpRequest.getParameter("idx")));
dto.setTitle(mpRequest.getParameter("title"));
dto.setWriter(mpRequest.getParameter("writer"));
dto.setContent(mpRequest.getParameter("content"));
dto.setCategory(mpRequest.getParameter("category"));
return dto;
}
}
에러를 띄운 부분
: 변수명(uploadFile) 이 같아야함 !!!
write.jsp에 있는 form | FileUtil |
<input type="file" name="uploadFile"> | File uploadFile = mpRequest.getFile("uploadFile"); |
내가 쓴 게시물 - myboard.jsp
: 페이징 추가
페이징을 위해서는 boardCount 등의 여러 변수들이 필요하다.
변수들이 제대로 구해지는지 확인할 수 있는 코드
: 이 코드를 넣고 잘 출력되는 것을 꼭 확인해야한다!!
<ul>
<li>게시글 개수 : ${boardCount }</li>
<li>요청받은 페이지 : ${paramPage }</li>
<li>paging.offset : ${paging.offset }</li>
<li>paging.fetch : ${paging.fetch }</li>
<li>paging.pageCount : ${paging.pageCount }</li>
<li>paging.begin : ${paging.begin }</li>
<li>paging.end : ${paging.end }</li>
</ul>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<main>
<c:set var="boardCount" value="${boardDAO.selectCount(login.userid) }"></c:set>
<c:set var="paramPage" value="${empty param.page ? 1 : param.page }"></c:set>
<c:set var="paging" value="${Paging.newInstance(paramPage, boardCount) }"></c:set>
<c:set var="list" value="${boardDAO.selectListByWriter(login.userid, paging) }"></c:set>
<table id="mypageList">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>삭제여부</th>
</tr>
</thead>
<tbody>
<c:forEach var="dto" items="${list }">
<tr class="clickable-row" data-href="${cpath}/view.jsp?idx=${dto.idx}">
<td>${dto.idx }</td>
<td>${dto.title }</td>
<td>${dto.writer }</td>
<td>${dto.deleted == 1 ? 'O' : 'X'}</td>
</tr>
</c:forEach>
<script>
document.addEventListener("DOMContentLoaded", function () {
var rows = document.querySelectorAll(".clickable-row");
rows.forEach(function (row) {
row.addEventListener("click", function () {
var href = row.getAttribute("data-href");
if (href) {
window.location.href = href;
}
});
});
});
</script>
</tbody>
</table>
<div class="frame mypageing">
<c:if test="${paging.prev }">
<a href="${cpath }/myboard.jsp?page=${paging.begin - 10}">[이전]</a>
</c:if>
<c:forEach var="i" begin="${paging.begin }" end="${paging.end }">
<a class="${paging.page == i ? 'bold' : ''}"
href="${cpath }/myboard.jsp?page=${i}">[${i }]</a>
</c:forEach>
<c:if test="${paging.next }">
<a href="${cpath }/myboard.jsp?page=${paging.end + 1}">[다음]</a>
</c:if>
</div>
</main>
</body>
Paging
: 게시글 페이징을 담당
package board;
public class Paging {
// 요청받은 페이지
private int page;
// 페이지 당 출력할 게시글의 수
private int perPage;
// 총 게시글의 개수 (삭제, 검색 반영)
private int boardCount;
// sql에서 사용할 건너뛸 개수의 값
private int offset;
// 건너 뛴 후 불러올 게시글의 수
private int fetch;
// 전체 페이지 개수
private int pageCount;
// 페이지를 n개씩 묶어 하나의 구역으로 설정 후 0부터 시작
private int section;
// 이전 구역이 있다면 true
private boolean prev;
// 다음 구역이 있다면 true
private boolean next;
// 구역의 시작 페이지
private int begin;
// 구역의 끝 페이지 (단, 끝 페이지가 pageCount보다 크면 안된다)
private int end;
// 생성자를 대신하는 static method
public static Paging newInstance(int page, int boardCount) {
return new Paging(page, boardCount);
}
private Paging(int page, int boardCount) {
this.page = page;
this.boardCount = boardCount;
perPage = 10;
offset = (page -1) * perPage;
fetch = perPage;
pageCount = boardCount /perPage;
pageCount += (boardCount % perPage != 0) ? 1 : 0;
section = (page -1) / 10;
begin = section * 10 + 1;
end = begin + 9;
prev = section != 0;
next = pageCount > end;
if (end > pageCount) {
end = pageCount;
next = false;
}
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getPerPage() {
return perPage;
}
public void setPerPage(int perPage) {
this.perPage = perPage;
}
public int getBoardCount() {
return boardCount;
}
public void setBoardCount(int boardCount) {
this.boardCount = boardCount;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getFetch() {
return fetch;
}
public void setFetch(int fetch) {
this.fetch = fetch;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public int getSection() {
return section;
}
public void setSection(int section) {
this.section = section;
}
public boolean isPrev() {
return prev;
}
public void setPrev(boolean prev) {
this.prev = prev;
}
public boolean isNext() {
return next;
}
public void setNext(boolean next) {
this.next = next;
}
public int getBegin() {
return begin;
}
public void setBegin(int begin) {
this.begin = begin;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
}
review
막힌 부분
: 변수들의 값이 제대로 안구해져서 페이징이 제대로 구현되지 않았었다.
알고보니 BoardDAO 에 있는
내 게시글 개수를 계산해주는 함수인 selectCount() 에 오타가 있었다..
수정완료 !!
// 게시글 개수 불러오는 함수
public int selectCount(String userid) {
int count = 0;
String sql = "select count(*) from board "
+ " where writer = ? "
+ " order by idx desc ";
try {
conn = ds.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userid);
rs = pstmt.executeQuery();
while (rs.next()) {
count = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {close();}
return count;
}
'project' 카테고리의 다른 글
[ jsp 프로젝트 ] 프로젝트 회고 (0) | 2023.12.22 |
---|---|
[ jsp 프로젝트 ] 게시글 저장 기능 (+ 대댓글) (0) | 2023.12.21 |
[ jsp 프로젝트 ] 게시판 기능 (검색 / script 를 이용한 무한스크롤) (0) | 2023.12.20 |
[ jsp 프로젝트 ] 회원기능 (0) | 2023.12.18 |
[ jsp 프로젝트 ] 여행 커뮤니티 사이트 만들기 (0) | 2023.12.17 |