01. 파일업로드의 개요
파일업로드(file upload)는 웹 브라우저에서 서버로 파일을 전송하여 서버에 저장하는 것을 말한다. 서버로 업로드할 수 있는 파일에는 텍스트 파일, 바이너리 파일, 이미지 파일, 문서 등 다양한 유형이 있다. 웹 브라우저에서 서버로 파일을 전송하기 위해 jsp 페이지에 폼 태그를 사용하고, 전송된 파일을 서버에 저장하기 위해 오픈 라이브러리를 이용해야 한다.
1.1 파일 업로드를 위한 jsp 페이지
웹 브라우저에서 서버로 파일을 전송하기 위해 jsp 페이지를 폼 태그를 작성 할 때 몇 가지 중요한 규칠을 따라야 하며 그 형식은 다음과 같다.
<form action = "JSP파일" method="POST" enctype="multipart/form-data">
<input type="rile" name="요청 파라미터 이름">
</form>
1. form 태그의 method 속성은 반드시POST 방식으로 설정해야 한다.
2. form 태그의 enctype 속성은 반드시 multipart/form-data 로 설정해야 한다.
3. form 태그의 action 속성은 파일 업로드를 처리할 jsp 파일로 설정해야 한다.
4. 파일 업로드를 위해 input 태그의 type 속성을 file 로 설정해야 한다. 만약 여러 파일을 업로드 하려면 2개이상의 input 태그를 사용하고 name 속성에 서로 다른 값을 설정한다.
다음은 jsp 페이지에 파일 업로드를 위한 폼 태그를 사용하는 에이다.
[파일 업로드를 위한 폼 태그 사용 예]
<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="process.jsp"> <!--1,2,3-->
<p> 제목 : <input type="text" name="title">
<p> 파일 : <input type="file" name="fileName"> <!--4-->
<p> <input type="submit" value="submit">
</form>
</body>
</html>
1.2 파일 업로드 처리방법
웹 브라우저에서 서버로 파일을 업로드하면 서버는 요청 파라미터를 분석하여 파일을 찾고 서버의 자원(파일 저장 폴더)에 저장하는 과정을 거친다. 이러한 파일 업로드의 처리는 단순한 자바의 코드로 작성하여 처리할 수 없어 다음과 같이 오픈 라이브러리인 cos.jar 나 commonsfileupload.jar 를 사용해야 한다.
파일 업로드 처리방법
종류 | 특징 | 필요한 라이브러리 |
MultipartRequest 이용하기 | 가장 간단한 방법 | cos.jar |
아파치 API 이용하기 | 편리하고 강력한 API제공 | commons-rileupload.jar commons-io.jar |
NOTE_ 파일 업로드를 위한 오픈 라이브러리 다운로드 사이트
- cos.jar 파일 : http://www.servlets.com
Servlets.com
Home What's New? COS File Upload Library Servlet Polls Mailing Lists Servlet Engines Servlet ISPs Servlet Tools Documentation Online Articles The Soapbox "Java Servlet Programming, Second Edition" "Java Enterprise Best Practices" Speaking & Slides About Ja
www.servlets.com
-commons-fileupload.jar 와 commons-io.jar 파일: http://commons.apache.org/downloads/
Apache Commons – Apache Commons
Downloads Binary and source releases and links into the archives may be obtained by selecting a project below Release Announcements We recommend that you subscribe to the Apache Announce mailing list to be notified when releases are made by the Commons pro
commons.apache.org
02.MultipartRequest 를 이용한 파일 업로드
MultipartRequest 는 웹 페이지에서 서버로 업로드되는 파일 자체만 다루는 클래스이다. 웹브라우저가 전송한 multipart/form-data 유형과 POST 방식의 요청 파라미터 등을 분석한 후 일반 데이터와 파일 데이터를 구분하여 파일 데이터에 접근한다. 또한 한글 인코딩값을 얻기 쉽고, 서버의 파일 저장 폴더에 동일한 파일명이 있으면 파일명을 자동으로 변경한다.
MultipartRequest 클래스는 cos(com.oreilly.servlet)패키지에 포함되어 있는 파일 업로드 컴포넌트로, 오픈 라이브러리 cos.jar 를 다음 배포사이트에서 직접 다운로드 해서 사용한다. 그리고 jsp 페이지에 page 디렉티브 태그의 import 속성을 사용하여 패키지 com.oreilly.servlet.* 을 설정해야 한다.
-배포사이트 : http://www.servlets.com/cos/
-다운로드 파일: cos-26Dec2008.zip
다운로드 받은 파일을 웹 애플림케이션의 /WebContent/WEB-INF/lib 폴더에 cos.jar 파일을 포함한다. 또는 서버 톰캣의 /common.lib 폴더와 자바 JDK의 lib 폴더에 cos.jar 파일을 포함한다.
MultipartRequest 클래스를 이용하여 파일을 업로드 하려면 먼저 MultipartRequest 객체를 생성한다. 그리고 생성된 객체를 통해 multipart/form-data 유형의 요청 파라미터를 읽어오고 파일을 업로드 한다.
2.1 MultipartRequest 클래스 생성
MultipartRequest 클래스는 다양한 생성자를 제공한다. 그중에서 한글 인코딩 값을 쉽게 얻을 수 있고, 업로드 되는 파일이 서버에 저장된 기존 파일과 중복될때 자동으로 변경해주는 생성자의 형식은 다음과 같다.
MultipartRuquest(javax.servlet.http.HttpServletRequest request,
java.langString saveDirectory,
int maxPostSize,
java.lang.String encoding,
FileRenamePolicy policy)
MultipartRequest 생성자의 매개변수
매개변수 | 설명 |
request | Request 내장 객체를 설정한다. |
saveDirectory | 서버의 파일 저장 경로를 설정한다 |
maxPostSize | 파일의 최대크기(바이트 단위)를 설정한다. 최대크기를 초과하면 IOException이 발생한다 |
encoding | 인코딩 유형을 설정한다 |
policy | 파일명 변경 정책을 설정한다. saveDirectory에 파일명이 중복되는 경우 덮어쓰기 여부를 설정하며, 설정하지않으면 덮어쓴다. |
다음은 MultipartRequest 클래스를 생성하는 예이다. 웹 브라우저에서 전송되는 파일을 서버의 C:\upload\ 경로에 저장하며, 파일의 최대 크기는 5MB(5x1,024x1,024B)이고, 파일명의 인코딩 유형은 utf-8로 설정했다. 또한 서버에 저장된 파일명 중복을 처리하기 위해 DefaultFileRenamePolicy 클래스를 사용했다. 즉 DefaultFileRenamePolicy 클래스는 서버에 동일한 파일이 존재하면 웹 브라우저에서 전송된 파일명 뒤에 숫자를 덧붙여 파일명이 중복되지 않게 한다. DefaultFileRenamePolict 클래스를 사용하려면 jsp 페이지에 page 디랜티브 태그의 import 속성으로 패키지 com.oreilly.servlet.multipart.*를 설정해야 한다.
[MultipartRequest 클래스 생성 예]
<%@ page impoer="com.oreilly.servlet.*"%>
<%@ page impoer="com.oreilly.servlet.multipart.*"%>
...(생략)....
MultipartRequest multi = new MultipartRequest(request,
"C://upload", 5*1024*1024, "utf-8",
new DefaultFileRenamePolicy())
2.2MultipartRequest 메소드
웹 브라우저에서 전송한 multipart/form-data 유형의 요청 파라미터를 쉽게 읽어오고 파일을 업로드할수 있도록 MultipartRequest 클래스에는 다양한 메소드가 있다. 웹 브라우저에서 전송되는 요청 파라미터 중 일반 데이터는 getParaneter()메소드로 값을 받을 수 있지만 파일일 경우 getFileNames()메소드를 이용하여 데이터를 받는다
MultipartRuquest 메소드의 종류
메소드 | 유형 | 설명 |
getContentType(String name) | String | 업로드된 파일의 콘텐츠 유형을 반환한다. 업로드된 파일이 없으면 null을 반환한다. |
getParameter(String name) | String | 요청 파라미터 이름이 name 인 값을 전달받는다. |
getParameterNames() | java.util.Enumeration | 요청 파라미터 이름을 Enumeration 객체 타입으로 반환한다. |
getFile(String name) | java.io.File | 서버에 업로드된 파일에 대한 파일 객체를 반환한다. 업로드된 파일이 없으면 null을 반환한다. |
getFileNames() | java.util.Enumeration | 폼페이지에 input 태그 내 type 속성 값이 file 로 설정된 요청 파라미터의 이름을 반환한다. |
getFilesystemName(String name) | String | 사용자가 설정하여 서버에 실제로 업로드된 파일명을 반환한다. 파일명이 중복되면 변경된 파일명을 반환한다. |
getOriginalFileName(String name) | String | 사용자가 업로드한 실제 파일명을 반환한다. 파일명이 중복되면 변경 전의 파일명을 반환한다. |
다음은 1절에서 작성한 ;jsp 페이지에서 입력된 제목과 파일을 전송하여 제목과 업로드할 파일에대한 정보를 출력하는 예이다.
[MultipartRequest 클래스의 메소드 사용 예: 요청 파라미터 정보 출력하기]
<%@ page contentType="text/html; charset=utf-8" %>
<%@ page import="com.oreilly.servlet.*"%>
<%@ page import="com.oreilly.servlet.multipart.*"%>
<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
<%
MultipartRequest multi = new MultipartRequest(request, "C:\\upload", 5*1024*1024, "utf-8", new DefaultFileRenamePolicy());
String title = multi.getParameter("title");
out.println("<h3>" + title + "</h3>");
Enumeration files = multi.getFileNames();
String name = (String) files.nextElement();
String filename = multi.getFilesystemName(name);
String original = multi.getOriginalFileName(name);
out.println("실제 파일 이름 : " +original + "<br>");
out.println("저장 파일 이름 : " +filename + "<br>");
%>
=MultipartRequest 클래스를 이용하여 파일 업로드 및 정보 출력하기=
1. 프로젝트 생성
2.cos.jar 라이브러리 등록
3.jsp페이지 작성
ch07/fileupload01.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form name="fileForm" method="post" enctype="multipart/form-data" action="fileupload01_process.jsp"> <!-- 파일 업로드를 위한 폼 태그/ method는 post, enctype 속성값은 multipart/form-data ,, 그리고 업로드된 파일을 처리하기 위한 action 속성값도 작성해야한다. -->
<p> 이름 : <input type="text" name="name"> <!-- 이름과 제목 값을 입력받도록 input 태그의 type 속성값을 text작성 하고 name속성을 작성한다. 아래도 같다 -->
<p> 제목 : <input type="text" name="subject">
<p> 파일 : <input type="file" name="fileName">
<p> <input type="submit" value="파일 올리기">
</form>
</body>
</html>
ch07/fileupload01_process.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<%@ page import="com.oreilly.servlet.*" %>
<%@ page import="com.oreilly.servlet.multipart.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%
//MultipartRequest 클래스를 생성하도록 서버파일 저장경로, 최대크기, 파일명의 인코딩 유형을 설정하고,
// 서버에 동일한 파일이 존재하면 파일명이 중복되지 않도록 DefaultFileRenamePolicy클래스로 작성한다
MultipartRequest multi = new MultipartRequest(request, "c:\\upload", 5 * 1024 * 1024, "utf-8", new DefaultFileRenamePolicy());
//폼 페이지에서 전송된 요청 파라미터를 받도록 MultipartRequest 객체 타입으로 getParameterNames()메소드를 작성한다.
Enumeration params = multi.getParameterNames();
//폼페이지에서 전송된 요청 파라미터가 없을 때까지 반복하도록 hasMoreElements()메소드를 작성.
while(params.hasMoreElements()){
//폼페이지에서 전송된 요청 파라미터의 이름을 가져오도록 nextElement()메소드를 작성.
String name = (String)params.nextElement();
//폼페이지에서 전송된 요청 파라미터의 값을 얻어오도록 위행에서 얻어온 요청 파라미터의 이름으로
//MultipartRequest 객체타입의 getParameter()메소드를 작성한다.
String value = multi.getParameter(name);
out.println(name + "="+value+"<br>"); //폼페이지에서 전송된 요청 파라미터의 값을 출력
}
out.println("_____________________<br>");
//폼 페이지에서 전송된 요청 파라미터 중 파일을 전달받도록 MultipartRequesst 객체타입의 getFileNamew()메소드 작성.
Enumeration files = multi.getFileNames();
//폼 페이지에서 전송된 요청 파라미터 중 파일이 없을 때까지 반복하도록 hasMoreElements()메소드 작성
while(files.hasMoreElements()){
String name = (String)files.nextElement();//폼페이지에서 전송된 요청 파라미터중 파일을 가져오도록 nextElement()메소드 작성.
//폼페이지에서 전송되어 서버에 업로드된 파일을 가져오도록 MultipartRequest 객체타입의 getFilesystemName()메소드 작성.
String filename = multi.getFilesystemName(name);
//폼페이지에서 전송된 파일이 서버에 저장되기 전의 파일 이름을 가져오도록 MultipartRequest객체타입의 getOriginalFileName()메소드 작성
String original =multi.getOriginalFileName(name);
//콘텐츠 유형을 가져오도록 getContentType()
String type = multi.getContentType(name);
//폼페이지에서 전송된 파일을 가져오도록 작성한 메소드 getFile()
File file = multi.getFile(name);
//위 행들에서 저장된 각각의 값을 출력.
out.println("요청 파라미터 이름 : " +name + "<br>");
out.println("실제 파일 이름 : " +original + "<br>");
out.println("저장 파일 이름 : " +filename + "<br>");
out.println("파일 컨텐츠 유형 : " +type + "<br>");
if(file != null){
out.println("파일크기 : " +file.length());
out.println("<br>");
}
}
%>
여기서 잠깐..!
fileupload01.jsp 페이지는 정상적으로 나왔다. 여기서 이름과 제목을 입력하고, 파일선택까지 한 다음에 파일 올리기로 submit 을 해주었는데,
그런데 상태 500 - 내부 서버 오류가 떴다.
자세히보니 Not a directory .....
바로 c드라이브에 upload 디렉토리를 직접 만들어줬다.
놀랍게도 ... 오류가 해결되었다
=MultipartRequest 클래스를 이용하여 여러파일 업로드 및 정보 출력하기=
/ch07/fileupload02.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form name="fileForm" method="post" enctype="multipart/form-data" action="fileupload02_process.jsp"> <!-- 파일 업로드를 위한 폼 태그/ method는 post, enctype 속성값은 multipart/form-data ,, 그리고 업로드된 파일을 처리하기 위한 action 속성값도 작성해야한다. -->
<p> 이름1 : <input type="text" name="name1"> <!-- 이름과 제목 값을 입력받도록 input 태그의 type 속성값을 text작성 하고 name속성을 작성한다. 아래도 같다 -->
<p> 제목1 : <input type="text" name="subject1">
<p> 파일1 : <input type="file" name="fileName1">
<p> 이름2 : <input type="text" name="name2">
<p> 제목2 : <input type="text" name="subject2">
<p> 파일2 : <input type="file" name="fileName2">
<p> 이름3 : <input type="text" name="name3">
<p> 제목3 : <input type="text" name="subject3">
<p> 파일3 : <input type="file" name="fileName3">
<p> <input type="submit" value="파일 올리기">
</form>
</body>
</html>
/ch07/fileupload02_process.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<%@ page import="com.oreilly.servlet.*" %>
<%@ page import="com.oreilly.servlet.multipart.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<%
MultipartRequest multi = new MultipartRequest(request,"C:\\upload", 5*1024*1024, "utf-8", new DefaultFileRenamePolicy());
String name1 = multi.getParameter("name1");
String subject1 = multi.getParameter("subject1");
String name2 = multi.getParameter("name2");
String subject2 = multi.getParameter("subject2");
String name3 = multi.getParameter("name3");
String subject3 = multi.getParameter("subject3");
Enumeration files = multi.getFileNames();
String file3 = (String)files.nextElement();
String filename3 = multi.getFilesystemName(file3);
String file2 = (String)files.nextElement();
String filename2 = multi.getFilesystemName(file2);
String file1 = (String)files.nextElement();
String filename1 = multi.getFilesystemName(file1);
%>
<table border="1">
<tr>
<th width="100">이름</th>
<th width="100">제목</th>
<th width="100">파일</th>
</tr>
<%
out.print("<tr><td>" + name1 + "</td>");
out.print("<td>" + subject1 + "</td>");
out.println("<td>" + filename1 + "</td></tr>");
out.print("<tr><td>" + name2 + "</td>");
out.print("<td>" + subject2 + "</td>");
out.println("<td>" + filename2 + "</td></tr>");
out.print("<tr><td>" + name3 + "</td>");
out.print("<td>" + subject3 + "</td>");
out.println("<td>" + filename3 + "</td></tr>");
%>
</table>
</body>
</html>
'JSP, Servlet, MySQL > JSP - webmarket' 카테고리의 다른 글
유효성 검사 : 상품 등록 데이터의 유효성 검사하기 (0) | 2023.09.08 |
---|---|
파일 업로드 : 상품 이미지 등록하기 2 /파일업로드 상태 500 내부 서버 오류/Not a directory (0) | 2023.09.08 |
폼 태그 : 상품 등록 페이지 만들기 2 (0) | 2023.09.04 |
폼 태그 : 상품 등록 페이지 만들기 (3) | 2023.09.03 |
내장 객체 : 상품 상세 정보 표시하기 2 (0) | 2023.09.03 |