today_is

[ jsp 프로젝트 ] 게시글 작성 (+ FileUtil 을 이용한 이미지 업로드 / 페이징) 본문

project

[ jsp 프로젝트 ] 게시글 작성 (+ FileUtil 을 이용한 이미지 업로드 / 페이징)

ye_rang 2023. 12. 21. 09:19

 

게시글 작성 - 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;
   }