아파치 파일 업로드 예 (Apache File Upload example)
commons-fileupload-1.3.1-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>