본문 바로가기

JSP/Apache Upload 01

Apache Upload

아파치 파일 업로드 예 (Apache File Upload example)

commons-fileupload-1.3.1-bin.zip

commons-io-2.4-bin.zip


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


위에서 안내한 순서에 따라 라이브러리를 다운로드했다면 압축을 해제하고 commons-fileupload-1.3.1.jar 파일과 commons-io-2.4.jar 파일을 Eclipse 3.3 의 Project Explorer의 WEB-INF/lib 안으로 import 하고 아래의 파일을 이용하여 실행 테스트 한다.

서버측에 업로드되어 서버의 파일 시스템에 저장되는 파일은 D:/upload/ 안에 저장되도록 설정했으므로 만약 다른 경로로 설정하려면 소스 중에서 D:/upload 부분을 C:/upload 등으로 변경해주면 된다.

uploadForm.html

form 태그의 속성에 enctype="multipart/form-data"method="post" 가 필수로 요구된다

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title>Upload page</title></head><body>
 <form action="apacheUpload.jsp" method="post" enctype="multipart/form-data" name="form1" id="form1">
   <table>
    <tr>
        <td><b>Multiple file Upload</b></td>
    </tr>
    <tr>
        <td><b>작성자: </b><input type="text" name="name" value="홍길동"></td>
    </tr>
    <tr>
        <td><b>설명:</b> <input type="text" name="desc" value="테스트용 업로드 파일"></td>
    </tr>
    <tr>
        <td>
         File 1: <input name="file" type="file">
        <td>
    </tr>
    <tr>
       <td>
       File 2:<input name="file" type="file">
       </td>
    </tr>
    <tr>
       <td>
        File 3:<input name="file" type="file">
       </td>
    </tr>
    <tr>
      <td>
        <input type="submit" name="Submit" value="Submit files"/>
      </td>
   </tr>
  </table>
 </form>
 </body>
 </html>


apacheUpload.jsp

<%@ page contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.io.File" %>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8">
<title> Apache ServletFileUpload example </title></head>
<body>
<table>
 <tr><td><h1>파일 업로드 결과 </h1></td></tr>
 <tr><td>
<%
 request.setCharacterEncoding("utf-8");
 boolean isMultipart = ServletFileUpload.isMultipartContent(request);
 if (!isMultipart) {
 }else {
    FileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
    List items = null;
    try {
       items = upload.parseRequest(request);
    } catch (FileUploadException e) {
     out.println("에러 1: "+e);
    }
    //Iterator itr = items.iterator(); // items 는 List 이므로 리스트 다루는 방법으로 해도 된다
    for(int i=0;i<items.size();i++) {
        FileItem item = (FileItem) items.get(i);
        if (item.isFormField()) { // 파일이 아닌 폼필드에 입력한 내용을 가져옴.
          if(item!=null && item.getFieldName().equals("name")) {
            String name = item.getString("utf-8");//form field 안에 입력한 데이터를 가져옴
            out.println("전송자:"+name+"<br>"); 
          }else if(item!=null && item.getFieldName().equals("desc")) {
            String desc = item.getString("utf-8");
            out.println("파일에 대한 설명:"+desc+"<br>");
          }
       } else { // 폼 필드가 아니고 파일인 경우
          try {
            String itemName = item.getName();//로컬 시스템 상의 파일경로 및 파일 이름 포함
            if(itemName==null || itemName.equals("")) continue;
            String fileName = FilenameUtils.getName(itemName);// 경로없이 파일이름만 추출함
            // 전송된 파일을 서버에 저장하기 위한 절차
            //String rootPath = getServletContext().getRealPath("/");
            File savedFile = new File("D:/upload/"+fileName); 
            item.write(savedFile);// 지정 경로에 파일을 저장함
       
            out.println("<tr><td><b>파일저장 경로:</b></td></tr><tr><td><b>"+savedFile+"</td></tr>");
            out.println("<tr><td><b><a href=\"DownloadServlet?file="+fileName+"\">"+fileName+"</a></td></tr>");
         } catch (Exception e) {
            out.println("서버에 파일 저장중 에러: "+e);
         }
      }    //end of else
    }     // end of for
 } 
%>
</table>

</body></html>


DownloadServlet.java

package org.dodream.jsp.upload;

import java.io.*;


import javax.servlet.*;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.*;


@WebServlet("/download")

public class DownloadServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {


 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


   request.setCharacterEncoding("utf-8");

   

   // 전송할 데이터의 인코딩 형식을 지정한다, 서버측에 업로드할 때 euc-kr 이었다면 euc-kr으로 하고 업로드 당시 utf-8이었다면 utf-8으로 설정한다


   response.setContentType("application/octet-stream;charset=utf-8");

   

   String fileName = request.getParameter("file");

   

   //아래처럼 attachment 를 사용하면 브라우저는 무조건 다운로드 창을 띄우고 파일명을 보여준다.


   // HTTP 헤더에 포함되는 파일명의 인코딩은 8859_1 형식이어야 한다


   // 톰캣설정에서 URIEncoding="utf-8"으로 했다면 GET 방식 요청의 문자 인코딩은 utf-8이므로


   // 서버측에는 utf-8 형식으로 전달되는데, HTTP헤더는 8859_1형식의 파일명을 포함해야 하므로


   // 원래 utf-8 형식에서 8859_1 형식으로 변환해야 HTTP 헤더에 파일명을 포함할 수 있다


   // utf-8 형식에서 8859_1형식으로 변환하는 예) 


   fileName = new String(fileName.getBytes("utf-8"),"8859_1");


   response.setHeader("Content-Disposition", "attachment;filename="+fileName+";");


   ServletOutputStream sos = null;

   try{

    sos = response.getOutputStream();

   }catch(Exception e){e.printStackTrace();}


   //다음과 같이 스트림을 열고 브라우저에 바이트 데이터를 전송해주면 된다.

   FileInputStream fio = null;


   // 현재 파일명에 적용된 문자인코딩이 8859_1 이라면 원래의 형식으로 변환해야 파일을 인식할 수 있고 내용을 읽어 올 수 있다


   // 원래의 형식이 euc-kr이었다면 fileName = new String(fileName.getBytes("8859_1"),"euc-kr"); 


   fileName = new String(fileName.getBytes("8859_1"),"utf-8");

   File inFile = new File("D:/upload/"+fileName);

   

   byte[] buf = null;

   if(inFile.exists()) {

      int len = (int)inFile.length();

      buf = new byte[len];

   }

   fio = new FileInputStream(inFile);

   fio.read(buf);

   sos.write(buf);

   sos.flush();

   fio.close();

   sos.close();

 }         

}


다음 서블릿은 위에서 JSP를 이용하여 서버측에서 파일 데이터를 수신한 것을 서블릿으로 작성해본 것
ApacheUploadServlet

package upload;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.io.*;

public class ApacheUploadServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  request.setCharacterEncoding("euc-kr");
 boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  if (!isMultipart) {
  }else {
     FileItemFactory factory = new DiskFileItemFactory();
     ServletFileUpload upload = new ServletFileUpload(factory);
     List items = null;
     try {
        items = upload.parseRequest(request);
     } catch (FileUploadException e) {
      e.printStackTrace();
     }
     Iterator itr = items.iterator();
     UploadInfo uploadInfo = new UploadInfo();
     while (itr.hasNext()) {
       FileItem item = (FileItem) itr.next();
       if (item.isFormField()) { // 파일이 아닌 폼필드에 입력한 내용을 가져옴.
         if(item!=null && item.getFieldName().equals("name")) {
           String name = item.getString("euc-kr");//form field 안에 입력한 데이터를 가져옴
           uploadInfo.setUserName(name);
           //System.out.println("전송자:"+name+"<br>");
         }else if(item!=null && item.getFieldName().equals("desc")) {
           String desc = item.getString("euc-kr");

           uploadInfo.setDesc(desc);
           //System.out.println("파일에 대한 설명:"+desc+"<br>");
         }
      } else { // 폼 필드가 아니고 파일인 경우
     try {
        String itemName = item.getName();//로컬 시스템 상의 파일경로 및 파일 이름 포함
        if(itemName==null || itemName.equals("")) continue;
        String fileName = FilenameUtils.getName(itemName);// 경로없이 파일이름만 추출함
        // 파일이름 중복검사 및 그에 따른 새이름 설정
        File f = checkExist(fileName);
        item.write(f);// 지정 경로에 파일을 저장함
        uploadInfo.getFileMap().put(fileName, f);
     } catch (Exception e) { e.printStackTrace(); }
    } // end of else
   }  // end of while
   request.setAttribute("uploadInfo", uploadInfo);
   request.getRequestDispatcher("/uploadResult.jsp").forward(request, response);
  }   // end of else
 }  // end of doPost
 
 /* 이미 동일이름의 파일이 존재하면 새로 저장되는 파일의 이름 변경 */
 private File checkExist(String fileName){
       File f = new File("D:/upload/"+fileName);
       if(f.exists()) {
        StringBuffer sb = new StringBuffer(fileName);
        sb.insert(sb.lastIndexOf("."),"-"+new Date().getTime());
        f = new File("D:/upload/"+sb.toString());
       }
  return f;
 }

}



위의 ApacheUploadServlet에서 사용된 UploadInfo 클래스
UploadInfo

package upload;

import java.io.*;
import java.util.*;

public class UploadInfo {
 
 private String userName;
 private String desc;
 private HashMap<String, File> fileMap = new HashMap<String, File>();
 
 public String getUserName() {
  return userName;
 }
 public String getDesc() {
  return desc;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public void setDesc(String desc) {
  this.desc = desc;
 }
 public HashMap<String, File> getFileMap() {
  return fileMap;
 }
 public void setFileMap(HashMap<String, File> fileMap) {
  this.fileMap = fileMap;
 }

}



ApacheUploadServlet에서 업로드 결과를 출력하는 JSP
uploadResult.jsp

<%@page import="java.util.*"%>
<%@page import="java.io.File"%>
<%@page import="upload.UploadInfo"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<% UploadInfo info = (UploadInfo)request.getAttribute("uploadInfo");
 HashMap<String,File> fileMap = info.getFileMap();
 Set<String> keys = fileMap.keySet();
 Iterator<String> iterator = keys.iterator();
%>
<!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=EUC-KR">
<title>파일 업로드 정보</title>
<style>
 th{text-align: right; height:30px;}
 td{text-align: left; height:30px;}
 caption { font-size: 17pt; }
</style>
</head>
<body>
<center><br/><br/>
 <table border="1" cellspacing="0" cellpadding="5">
  <caption>파일 업로드 결과</caption>
  <tr><th>작성자</th><td><%=info.getUserName()%></td></tr>
  <tr><th>설 명</th><td><%=info.getDesc()%></td></tr>
  <tr><th>원래 파일명</th><td>
   <%
    
    while(iterator.hasNext()) {
     String originName = iterator.next();
     String changedName = fileMap.get(originName).getName();%>
     <a href="DownloadServlet?file=<%=originName%>"><%=originName%></a> :
     <%=changedName%>
     <br/>
<%    }
   %>
  </td></tr>
 </table>

</center>
</body>
</html>