DB를 이용한 파일업로드 개념
파일 정보를 저장할 테이블 생성
create table fileTest (num number(7) primary key, subject varchar2(50) not null, saveFileName varchar2(50), originalFileName varchar2(50)); |
서블릿 매핑 web.xml 설정
<!-- Servlet 파일 업로드 --> <servlet> <servlet-name>fileTestServlet</servlet-name> <servlet-class>com.fileTest.FileTestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>fileTestServlet</servlet-name> <url-pattern>/file/*</url-pattern> </servlet-mapping> |
FileTestDTO 생성
package com.file; public class FileTestDTO { private int num; private String subject; private String saveFileName; private String originalFileName;
//getter,setter생성 } |
FileTestDAO 생성
파일 데이터는 수정이 필요 없으므로 update문은 사용하지 않음(등록,삭제,조회만 진행)
public class FileTestDAO {
private Connection conn = null; public FileTestDAO(Connection conn){ this.conn = conn; }
//레코드 번호 public int getMaxNum(){ int maxNum = 0; PreparedStatement pstmt = null; ResultSet rs = null; String sql;
try {
sql = "select nvl(max(num),0) from fileTest"; pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); if(rs.next()){ maxNum = rs.getInt(1); } rs.close(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } return maxNum; }
//파일데이터 입력 public void insertData(FileTestDTO dto){
PreparedStatement pstmt = null; String sql; try { sql = "insert into fileTest (num,subject,saveFileName, "; sql += "originalFileName) values (?,?,?,?)";
pstmt = conn.prepareStatement(sql); pstmt.setInt(1, dto.getNum()); pstmt.setString(2, dto.getSubject()); pstmt.setString(3, dto.getSaveFileName()); pstmt.setString(4, dto.getOriginalFileName());
pstmt.executeUpdate(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } }
//파일데이터 전체조회 public List<FileTestDTO> getList(int start, int end){
List<FileTestDTO> lists = new ArrayList<FileTestDTO>(); PreparedStatement pstmt = null; ResultSet rs = null; String sql;
try { sql = "select * from (select rownum rnum,num,subject,saveFileName,originalFileName "; sql += "from fileTest order by num desc) "; sql += "where rnum >= ? and rnum <=? ";
pstmt = conn.prepareStatement(sql); pstmt.setInt(1, start); pstmt.setInt(2, end);
rs = pstmt.executeQuery(); while(rs.next()){ FileTestDTO dto = new FileTestDTO(); dto.setNum(rs.getInt("num")); dto.setSubject(rs.getString("subject")); dto.setSaveFileName(rs.getString("saveFileName")); dto.setOriginalFileName(rs.getString("originalFileName")); lists.add(dto); } rs.close(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } return lists; }
//특정 데이터 조회 public FileTestDTO getReadData(int num){
FileTestDTO dto = null; PreparedStatement pstmt = null; ResultSet rs = null; String sql; try { sql = "select num,subject,saveFileName,originalFileName "; sql += "from fileTest where num = ? ";
pstmt = conn.prepareStatement(sql); pstmt.setInt(1, num); //매개변수로 받은 num. where조건에 넣어줌 rs = pstmt.executeQuery(); if(rs.next()){ dto = new FileTestDTO();
dto.setNum(rs.getInt("num")); dto.setSubject(rs.getString("subject")); dto.setSaveFileName(rs.getString("saveFileName")); dto.setOriginalFileName(rs.getString("originalFileName")); } rs.close(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } return dto; }
//파일데이터 삭제 public void deleteData(int num){
PreparedStatement pstmt = null; String sql; try { sql = "delete fileTest where num=?"; pstmt = conn.prepareStatement(sql); pstmt.setInt(1,num); pstmt.executeUpdate(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } }
//데이터 카운트 public int getDataCount(){ int totalDataCount = 0; PreparedStatement pstmt =null; ResultSet rs = null; String sql; try { sql = "select nvl(count(*),0) from fileTest "; pstmt= conn.prepareStatement(sql); rs = pstmt.executeQuery(); if(rs.next()) totalDataCount = rs.getInt(1);
rs.close(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } return totalDataCount; } }
|
FileTestServlet 서블릿 클래스 생성
public class FileTestServlet extends HttpServlet{ private static final long serialVersionUID = 1L;
protected void forward(HttpServletRequest req, HttpServletResponse resp, String url) throws ServletException, IOException { //포워드 RequestDispatcher rd = req.getRequestDispatcher(url); rd.forward(req, resp); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //dopost 메소드 호출 doPost(req, resp); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); Connection conn = DBCPConn.getConnection(); FileTestDAO dao = new FileTestDAO(conn); //페이징 처리 MyUtil myUtil = new MyUtil(); String cp = req.getContextPath(); String uri = req.getRequestURI(); String url;
//파일 업로드 위치 지정 String root = getServletContext().getRealPath("/") ; String path = root + File.separator + "pds" + File.separator + "saveFile";//File.separator를 역슬래시로 입력해도 가능 //해당경로에 있는 파일로 객체 생성 File f = new File(path);
//파일 존재하지 않으면 디렉토리 생성 if(!f.exists()){ f.mkdirs(); }
if(uri.indexOf("write.do")!=-1){ //파일업로드 페이지 호출 url = "/fileTest/write.jsp"; forward(req, resp, url);
}else if(uri.indexOf("write_ok.do")!=-1){
//파일업로드 페이지 호출(DAO실행) String encType = "UTF-8"; int maxSize = 10*1024*1024; //물리적 파일 업로드 (cos.lib의 MultipartRequest 사용 ) MultipartRequest mr = new MultipartRequest(req, path, maxSize, encType, new DefaultFileRenamePolicy());
//DB에 파일정보 입력 //업로드한 파일로부터 정보 추출 if(mr.getFile("uploadFile")!=null){//null이 아니면 파일이 제대로 업로드된것 FileTestDTO dto = new FileTestDTO(); int maxNum = dao.getMaxNum(); dto.setNum(maxNum+1); dto.setSubject(mr.getParameter("subject")); dto.setSaveFileName(mr.getFilesystemName("uploadFile")); dto.setOriginalFileName(mr.getOriginalFileName("uploadFile")); dao.insertData(dto); }
//list.do 페이지로 리다이렉트 url = cp + "/file/list.do"; resp.sendRedirect(url);
}else if(uri.indexOf("list.do")!=-1){
//파일업로드 내역 조회 페이지 호출(DAO실행) String pageNum = req.getParameter("pageNum"); int currentPage = 1; //처음 띄우는 리스트 페이지
if(pageNum!=null){ currentPage = Integer.parseInt(pageNum); }
int dataCount = dao.getDataCount(); int numPerPage = 5; int totalPage = myUtil.getPageCount(numPerPage, dataCount);
if(currentPage>totalPage) currentPage = totalPage;
int start = (currentPage-1)*numPerPage+1; int end = currentPage*numPerPage;
String listUrl = cp+"/file/list.do"; List<FileTestDTO> lists = dao.getList(start,end); String pageIndexList = myUtil.pageIndexList(currentPage, totalPage, listUrl);
//다운로드경로 String downloadPath = cp + "/file/download.do"; //삭제경로 String deletePath = cp + "/file/delete.do";
//파일정보 테이블을 리스트로 전달 req.setAttribute("lists", lists); req.setAttribute("pageNum", pageNum); req.setAttribute("downloadPath", downloadPath); req.setAttribute("deletePath", deletePath); req.setAttribute("pageIndexList", pageIndexList);
//list.jsp 페이지로 포워드 url = "/fileTest/list.jsp"; forward(req, resp, url);
}else if(uri.indexOf("download.do")!=-1){
//파일 다운로드 int num = Integer.parseInt(req.getParameter("num")); FileTestDTO dto = dao.getReadData(num);
if(dto==null) return;//다운로드할 파일이 없으면 종료
//파일을 정상적으로 받으면 true, 아닐경우 false boolean flag = FileManager.doFileDownload(resp, dto.getSaveFileName(), dto.getOriginalFileName(), path);
//물리적 파일은 지웠는데 DB상의 정보에서는 삭제되지 않은 경우와 같이 //두 데이터가 자동으로 동기화가 되지 않는 문제가 있음. 그래서 boolean 이용
//다운로드 오류 발생시 flag에 false 반환. 이 때, 오류 메세지 출력 if(flag==false){ resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.print("<script type='text/javascript'>"); out.print("alert('download error');"); out.print("history.back()");//확인버튼을 누르면 이전화면으로 돌려줌 out.print("</script>"); }
}else if(uri.indexOf("delete.do")!=-1){
int num = Integer.parseInt(req.getParameter("num")); int pageNum = Integer.parseInt(req.getParameter("pageNum"));
FileTestDTO dto = dao.getReadData(num);
//물리적 파일 삭제 FileManager.doFileDelete(dto.getSaveFileName(), path);
//테이블 정보 삭제 dao.deleteData(num);
//삭제 진행 후 리스트 페이지로 리다이렉트 url = cp + "/file/list.do?pageNum="+pageNum; resp.sendRedirect(url); } } } |
FileManager (물리적 파일 등록/삭제할 클래스)
public class FileManager {
파일다운로드 saveFileName : 서버에 저장된 파일명 originalFileName : 클라이언트가 업로드한 파일명 path : 서버에 저장된 실제 경로 서버에 있는 파일을 읽어서 클라이언트에게 내려보내는 것이기 때문에 req가 아니라 resp가 매개변수로 사용 //파일업로드 public static boolean doFileDownload(HttpServletResponse response, String saveFileName, String originalFileName, String path){
try { //파일경로 String filePath = path + File.separator + saveFileName ;
//클라이언트가 설정한 파일명이 없을경우 서버에 저장된 파일명으로 입력 if(originalFileName==null || originalFileName.equals("")){ originalFileName = saveFileName; }
//파일을 다운받아 클라이언트 컴에 파일이름 생성시 한글깨짐 방지 originalFileName = new String(originalFileName.getBytes("euc-kr"),"ISO-8859-1");
File f = new File(filePath);
if(!f.exists()){ return false; //파일이 존재하지 않으면 stop }
//파일의 종류. ContentType 을 설정 response.setContentType("application/octet-stream");// .txt 와 같이 파일확장자 앞에 붙는 .을 octet-stream라고 함 //헤더정보 response.setHeader("Content-disposition", "attachment;fileName="+originalFileName);
//서버에서 클라이언트로 내려보낼 때, Fileinputstream으로 파일을 읽은 후 bis에 넣은 것 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));//f로 줘도 되고 filepath로 줘도 됨
//읽은 파일을 내보낼 때 outputstream 사용 OutputStream out = response.getOutputStream();
int data; byte bytes[] = new byte[4096];
while((data=bis.read(bytes,0,4096))!=-1){ out.write(bytes,0,data); } out.flush(); out.close(); bis.close(); } catch (Exception e) { System.out.println(e.toString()); return false; } return true; } //파일삭제 public static void doFileDelete(String fileName, String path){ try {
String filePath = path + File.separator + fileName; File f = new File(filePath); //파일의 경로를 찾아가서 존재할 경우 삭제 if(f.exists()){ f.delete();//물리적 파일삭제 } } catch (Exception e) { System.out.println(e.toString()); } } } |
파일업로드 페이지 write.jsp
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="<%=cp%>/file/write_ok.do" method="post" enctype="multipart/form-data"> 제목: <input type="text" name="subject"/><br/> 파일: <input type="file" name="uploadFile"/><br/> <input type="submit" value="전송"/><br/> </form> </body> </html> |
파일 목록 조회 페이지 list.jsp
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>파일 목록</title> </head> <body> <br/><br/> <table width="500" align="center" > <tr> <td align="right" colspan="4"> <input type="button" value="글쓰기" onclick="javascript:location='<%=cp%>/file/write.do';"/> </td> </tr> <tr> <td align="center" width="50">번호</td> <td align="left" width="150">제목</td> <td align="left" width="250">파일</td> <td align="center" width="50">삭제</td> </tr> <c:forEach var="dto" items="${lists }"> <tr> <td align="center" width="50">${dto.num }</td> <td align="left" width="150">${dto.subject }</td> <td align="left" width="250"> <a href="${downloadPath }?num=${dto.num }"> ${dto.originalFileName }</a></td> <td align="center" width="50"> <a href="${deletePath}?num=${dto.num }&pageNum=${pageNum }">삭제</a></td> </tr> </c:forEach> <tr> <td align="center" colspan="4"> <c:if test="${dataCount!=0 }"> ${pageIndexList } </c:if> <c:if test="${dataCount==0 }"> 등록된 파일이 없습니다 </c:if> </td> </tr> </table> </body> </html> |
batch 파일을 이용한 Tomcat Server 시작
1. webapps 위치로 .war 파일 export
경로 : D:\java\apache-tomcat-7.0.92\webapps
2. 이클립스에서 설정해놓은 resource 관련 코드가 적용이 되어있지 않은것을 확인할 수 있음.
이클립스에 등록된 내용이 자동으로 동기화가 되지않는다. 복사해서 txt 파일로 편집하여 반영.
3. 이클립스를 실행하지 않더라도 서버 shutdown, startup 킬수있음
경로 D:\java\apache-tomcat-7.0.92\bin
파일 업로드 위치 지정
String root = getServletContext().getRealPath("/") ;
String path = root + File.separator + "pds" + File.separator + "saveFile"; //File.separator를 역슬래시로 입력해도 가능
이클립스로 서버 시작시 파일 저장 경로
:\java\work\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\study\pds\saveFile
bat파일로 서버 시작시 파일 저장 경로
D:\java\apache-tomcat-7.0.92\webapps\study\pds\saveFile
파일명이 한글으로 오류날 때
'Dev > JSP & Servlet' 카테고리의 다른 글
Servlet - ServletContextListener 구현 (0) | 2019.03.06 |
---|---|
필터구현 (로그인 검사, 캐릭터 인코딩, 시간 측정) (0) | 2019.03.06 |
cos.jar를 이용한 파일 업로드(1)-cos.lib설치, 파일등록, 파일정보 조회 (0) | 2019.02.28 |
쿠키의 개요, 생성, 전달, 삭제 (0) | 2019.02.28 |
Servlet - 회원가입,로그인 페이지 만들기 (0) | 2019.02.27 |