<input type="file" name="image">와 같이 type을 file로 지정한다.
버튼을 클릭하면 action.jsp로 이동한다. (action.jsp에서 사진 업로드 처리)
action.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.MultipartRequest" %> <!-- request 대신 -->
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %> <!-- 파일이름 중복을 피할 수 있도록 -->
<%
// 웹 프로젝트 위치에 넣어도 된다 (이클립스에서 사진 추가되는 것을 실시간으로 확인 가능)
// MultipartRequest mr = new MultipartRequest(request, "C:/Users/fjdks/Desktop/erp/WebContent/image", 1024*1024*1024, "utf-8", new DefaultFileRenamePolicy());
MultipartRequest mr = new MultipartRequest(request, request.getRealPath("/image"), 1024*1024*1024, "utf-8", new DefaultFileRenamePolicy());
System.out.println("저장되는 경로(실제 서버) : "+request.getRealPath("/image"));
String fileName = mr.getFilesystemName("image");
System.out.println("사진 이름 : "+fileName);
%>
MultipartRequest를 통해 사진을 저장한다. (웹 프로젝트 위치 or 서버 위치)
request.getRealPath()로 실제 서버 위치에 접근할 수 있다.
(이클립스에서는 사진이 추가되는 것이 보이지 않는다. 웹 프로젝트 위치로 접근하면 사진이 추가되는 것을 실시간으로 확인할 수 있다)
form.jsp에서 enctype="multipart/form-data"으로 받아왔기 때문에, request.getParameter()를 사용할 수 없다.
파일명은 mr.getFilesystemName()을 사용하여 받고, 일반적인 값은 mr.getParameter()를 통해 받아온다.
* request.getRealPath("/image")가 작동되도록 WebContent 아래에 image 파일을 생성했다 *
📂 이전 파일 삭제
action.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.MultipartRequest" %> <!-- request 대신 -->
<%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %> <!-- 파일이름 중복을 피할 수 있도록 -->
<%@ page import="java.io.File" %>
<%
// 이렇게 원하는 위치를 직접 넣어도 되긴 함(프로젝트 파일에 실시간으로 추가되는거 볼 수 있음 ㅋㅋ)
// MultipartRequest mr = new MultipartRequest(request, "C:/Users/fjdks/Desktop/erp/WebContent/image", 1024*1024*1024, "utf-8", new DefaultFileRenamePolicy());
MultipartRequest mr = new MultipartRequest(request, request.getRealPath("/image"), 1024*1024*1024, "utf-8", new DefaultFileRenamePolicy());
System.out.println("저장되는 경로(실제 서버) : "+request.getRealPath("/image"));
String fileName = mr.getFilesystemName("image");
System.out.println("저장된 사진 이름 : "+fileName);
// 실제로는 이전 사진 이름을 DB에서 불러온다
String beforeImg = "fullmetalAlchemist.PNG";
// 이전 사진명을 통해 실제로 삭제될 사진을 가져온다
String deleteImgName = request.getRealPath("/image/") + beforeImg;
File deleteImg = new File (deleteImgName);
// 이전 사진이 경로에 존재한다면 삭제한다
if (deleteImg.exists() && deleteImg.isFile()){
deleteImg.delete();// 사진 삭제
System.out.println("삭제된 이전 사진 : "+beforeImg);
}
%>
임시로 이전 사진의 이름을 "fullmetalAlchemist.PNG"로 설정하였지만 실제로는 DB에서 값을 받아와야 한다.
경로 + 사진 이름까지 담겨진 deleteImgName 변수를 File 형태로 만든다.
만약 deleteImg의 경로에 파일이 존재하고 deleteImg가 파일이라면, 해당 사진(이전 사진)을 삭제한다.
<!-- 상품 목록 출력 -->
<%
// 페이지
int currentPage = 1;
if(request.getParameter("currentPage")!=null){
currentPage = Integer.parseInt(request.getParameter("currentPage"));
}
System.out.println(currentPage+" <--selectEbookList currentPage");
final int ROW_PER_PAGE = 10; // 페이지에 보일 주문 개수
int beginRow = (currentPage-1)*ROW_PER_PAGE; // 리스트 목록 시작 부분
// 전체 목록
EbookDao ebookDao = new EbookDao();
// 화면에 보일 리스트를 추출해오는 함수(리스트 시작 부분, 받아올 리스트 개수)
ArrayList<Ebook> ebookList = ebookDao.selectEbookList(beginRow, ROW_PER_PAGE);
%>
<h2>전체 상품 목록</h2>
<!-- 상품 목록 출력 -->
<table class="table" border="1">
<tr>
<%
int i = 0;
// 반복을 통해 카테고리 목록을 표로 출력
for(Ebook e : ebookList){
%>
<td>
<div><a href=""><img src="<%=request.getContextPath() %>/image/<%=e.getEbookImg() %>" width="200" height="200"></a></div>
<div><a href=""><%=e.getEbookTitle() %></a></div>
<div>₩ <%=e.getEbookPrice() %></div>
</td>
<%
i+=1; // for문 끝날때마다 i는 1씩 증가
if(i%5==0){
%>
</tr><tr> <!-- 줄바꿈 -->
<%
}
}
%>
</tr>
</table>
<div></div>
<!-- 페이지 -->
<%
// 페이징을 위해 구해야 할 마지막 페이지 연산
int lastPage;
int currentnumPage=0; // 현재 페이지가 몇번째 묶음인지(이전,다음 구현을 위함)
int lastnumPage=0; // 마지막 페이지가 몇번째 묶음인지(마지막 페이지에서 다음이 나오지 않도록 하기 위함)
lastPage = ebookDao.selectEbookListLastPage(ROW_PER_PAGE); // 상품의 개수를 통해 마지막 페이지가 몇번인지 추출
%>
<ul class="pagination body-back-color">
<%
if(currentPage!=1){
%>
<li class="page-item"><a class="page-link" href="<%=request.getContextPath() %>/index.jsp?currentPage=<%=1 %>">처음</a></li>
<%
}
if(currentPage%ROW_PER_PAGE==0){ // 현재 페이지가 몇번째 묶음인지
currentnumPage =(currentPage/ROW_PER_PAGE)-1;
} else{
currentnumPage = currentPage/ROW_PER_PAGE;
}
%>
<%
if((currentnumPage)>0){ // 이전
%>
<li class="page-item"><a class="page-link" href="<%=request.getContextPath() %>/index.jsp?currentPage=<%=ROW_PER_PAGE*(currentnumPage-1)+1 %>">이전</a></li>
<%
}
for(int i=0;i<ROW_PER_PAGE;i++){ // 중간 번호들
if(lastPage>=(ROW_PER_PAGE*currentnumPage)+i+1){
%>
<li class="page-item"><a class="page-link" href="<%=request.getContextPath() %>/index.jsp?currentPage=<%=(ROW_PER_PAGE*currentnumPage)+i+1 %>"><%=(ROW_PER_PAGE*currentnumPage)+i+1 %></a></li>
<%
}
}
if(lastPage%ROW_PER_PAGE==0){ // 마지막 페이지가 몇번째 묶음인지
lastnumPage =(lastPage/ROW_PER_PAGE)-1;
} else{
lastnumPage = lastPage/ROW_PER_PAGE;
}
if(lastnumPage>currentnumPage){
%>
<li class="page-item"><a class="page-link" href="<%=request.getContextPath() %>/index.jsp?currentPage=<%=ROW_PER_PAGE*(currentnumPage+1)+1 %>">다음</a></li>
<%
}
if(currentPage!=lastPage && lastPage!=0){
%>
<li class="page-item"><a class="page-link" href="<%=request.getContextPath() %>/index.jsp?currentPage=<%=lastPage %>">맨끝</a></li>
<%
}
%>
</ul>
- currentPage(현재페이지), beginRow(리스트 시작 위치), ROW_PER_PAGE(화면에 보일 리스트 개수 및 하단 페이징 단위), lastPage(마지막 페이지), currentNumPage(현재 페이지가 위치한 묶음 단위<이전, 다음을 위함>), lastnumPage(마지막 페이지가 위치한 묶음 단위<다음 버튼의 오류 방지>)
- 각 변수들의 사용 목적을 숙지하면 코드를 이해하기 좋습니다.
EbookDao.java
// [관리자 & 고객] 전자책 목록 전체 출력
public ArrayList<Ebook> selectEbookList(int beginRow, int rowPerPage) throws ClassNotFoundException, SQLException{
ArrayList<Ebook> list = new ArrayList<>();
// mariaDB 연동
Class.forName("org.mariadb.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mariadb://127.0.01:3307/shop", "root", "java1004");
String sql = "select ebook_no ebookNo, category_name categoryName, ebook_title ebookTitle, ebook_img ebookImg, ebook_price ebookPrice, ebook_state ebookState from ebook order by create_date desc limit ?,?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, beginRow);
stmt.setInt(2, rowPerPage);
System.out.println("ebook 목록 출력 stmt : "+stmt);
ResultSet rs = stmt.executeQuery();
// 각 전자책의 정보를 리스트에 담는다
while(rs.next()) {
Ebook ebook = new Ebook();
ebook.setEbookNo(Integer.parseInt(rs.getString("ebookNo")));
ebook.setCategoryName(rs.getString("categoryName"));
ebook.setEbookTitle(rs.getString("ebookTitle"));
ebook.setEbookImg(rs.getString("ebookImg"));
ebook.setEbookPrice(rs.getInt("ebookPrice"));
ebook.setEbookState(rs.getString("ebookState"));
list.add(ebook);
}
rs.close();
stmt.close();
conn.close();
return list;
}
// [관리자] 전자책 마지막 페이지 연산
public int selectEbookListLastPage(int rowPerPage) throws ClassNotFoundException, SQLException {
DBUtil dbUtil = new DBUtil();
Connection conn = dbUtil.getConnection();
// 전체 페이지수 구하기
PreparedStatement stmt;
String sql = "select count(*) from ebook";
stmt = conn.prepareStatement(sql);
System.out.println("전체 전자책 수 stmt : "+stmt);
ResultSet rs = stmt.executeQuery();
rs.next();
int totalData = rs.getInt("count(*)");
int lastPage= totalData/rowPerPage; // 마지막 페이지 번호
if(totalData%rowPerPage!=0){
lastPage +=1;
}
rs.close();
stmt.close();
conn.close();
return lastPage;
}
[전자책 목록 전체 출력]
- 전자책 목록을 mariaDB에서 받아온 후, ArrayList에 담는 메서드 입니다. 쿼리에서 중요한 부분은 limit입니다.
- limit ?,? => 첫번째 물음표에 테이블에서 추출할 리스트의 시작부분을 넣고, 두번째 물음표에 시작부분 부터 몇개의 리스트를 추출할 것인지를 넣는 것 입니다.
[마지막 페이지 연산]
- 추출할 요소의 수를 받아온 후 rowPerPage를 통해 마지막 페이지가 몇인지 구합니다.