練功房推薦書單

  • 猛虎出柙雙劍合璧版--最新 OCA / OCP Java SE 7 Programmer 專業認證 (電子書)
  • 流浪教師存零股存到3000萬(全新增修版)(書+DVD)
  • 開始在關西自助旅行(京都‧大阪‧神戶‧奈良)(全新增訂版)
  • 不敗教主的300張股票存股術

JSP精選實用範例(二):檔案上傳 RSS feed
Forum Index » 網頁程式設計 Web Development
Author Message
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
預先安裝函式庫:Apache Commons FileUpload, Apache Commons IO
程式碼:
fileupload.html:
<html>

<head>
<title>File Upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
</head>
<body>

檔案上傳



<form name="upload" enctype="multipart/form-data" method="post" action="fileupload.jsp">

上傳檔案: <input type="file" name="file" size="20" maxlength="20" />


檔案說明: <input type="text" name="filedesc" size="30" maxlength="50" />


<input type="submit"value="上傳" /> <input type="reset" value="清除" />


</form>

</body>
</html>

fileupload.jsp:

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.io.File"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.util.List"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<%
String saveDirectory = application.getRealPath("/upload");

// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
out.println("isMultipart="+isMultipart+"<br>");

// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
private long megaBytes = -1;
public void update(long pBytesRead, long pContentLength, int pItems) {
long mBytes = pBytesRead / 1000000;
if (megaBytes == mBytes) {
return;
}
megaBytes = mBytes;
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength
+ " bytes have been read.");
}
}
};
upload.setProgressListener(progressListener);

// Parse the request
List /* FileItem */ items = upload.parseRequest(request);

// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();

if (item.isFormField()) {
// Process a regular form field
//processFormField(item);
String name = item.getFieldName();
String value = item.getString();
value = new String(value.getBytes("UTF-8"), "ISO-8859-1");
out.println(name + "=" + value+"<br>");
} else {
// Process a file upload
//processUploadedFile(item);
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
out.println("fieldName="+fieldName+"<br>");
out.println("fileName="+fileName+"<br>");
out.println("contentType="+contentType+"<br>");
out.println("isInMemory="+isInMemory+"<br>");
out.println("sizeInBytes="+sizeInBytes+"<br>");
if (fileName != null && !"".equals(fileName)) {
fileName= FilenameUtils.getName(fileName);
out.println("fileName saved="+fileName+"<br>");
File uploadedFile = new File(saveDirectory, fileName);
item.write(uploadedFile);
}
}
}
%>

注意:
請自行在您網頁應用程式的根目錄下建立一個upload的子目錄,並確認或設定讓Tomcat對upload目錄具有可寫入權限(Linux環境)。
參考資料:
http://commons.apache.org/proper/commons-fileupload/using.html
 Filename fileupload.jsp [Disk] Download
 Description 網頁上傳處理程式
 Filesize 3 Kbytes
 Downloaded:  446 time(s)

 Filename fileupload.html [Disk] Download
 Description 上傳表單網頁
 Filesize 556 bytes
 Downloaded:  388 time(s)


分享經驗 累積智慧
[WWW]
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
使用Streaming API的方式:
程式碼:
fileupload_streaming.html:

<html>
<head>
<title>File Upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
</head>
<body>

檔案上傳



<form name="upload" enctype="multipart/form-data" method="post" action="fileupload_streaming.jsp">

上傳檔案: <input type="file" name="file" size="20" maxlength="20">


檔案說明: <input type="text" name="filedesc" size="30" maxlength="50">


<input type="submit"value="上傳"> <input type="reset" value="清除">


</form>

</body>
</html>

fileupload_streaming.jsp:
<%@ page contentType="text/html; charset=UTF-8"%>

<%@ page import="java.io.*"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.fileupload.util.Streams"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<%
String saveDirectory = application.getRealPath("/upload");

// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
out.println("isMultipart="+isMultipart+"<br>");

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();

//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
private long megaBytes = -1;
public void update(long pBytesRead, long pContentLength, int pItems) {
long mBytes = pBytesRead / 1000000;
if (megaBytes == mBytes) {
return;
}
megaBytes = mBytes;
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength
+ " bytes have been read.");
}
}
};
upload.setProgressListener(progressListener);

// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
String value = Streams.asString(stream);
out.println(name + "=" + value+"<br>");
} else {
System.out.println("File field " + name + " with file name "
+ item.getName() + " detected.");
// Process the input stream
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
out.println("fieldName="+fieldName+"<br>");
out.println("fileName="+fileName+"<br>");
out.println("contentType="+contentType+"<br>");
if (fileName != null && !"".equals(fileName)) {
fileName= FilenameUtils.getName(fileName);
out.println("fileName saved="+fileName+"<br>");
File uploadedFile = new File(saveDirectory, fileName);
FileOutputStream uploadedFileStream =
new FileOutputStream(uploadedFile);
Streams.copy(stream, uploadedFileStream, true);
}
}
}
%>

參考資料:
http://commons.apache.org/fileupload/streaming.html
 Filename fileupload_streaming.html [Disk] Download
 Description 上傳表單網頁
 Filesize 543 bytes
 Downloaded:  156 time(s)

 Filename fileupload_streaming.jsp [Disk] Download
 Description 網頁上傳處理程式
 Filesize 3 Kbytes
 Downloaded:  171 time(s)


分享經驗 累積智慧
[WWW]
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
增加檔案大小限制及檔案類型的篩選:
程式碼:
fileupload_control.html:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>File Upload</title>
<style type="text/css">
<!--
.topic {color: #FF0000; font-size: 1.5em; font-weight: bold}
-->
</style>
</head>
<body>
<p class="topic">檔案上傳



<form name="upload" enctype="multipart/form-data" method="post" action="fileupload_control.jsp">

上傳檔案: <input type="file" name="file" size="20" maxlength="20" />


檔案說明: <input type="text" name="filedesc" size="30" maxlength="50" />


<input type="submit"value="上傳" /> <input type="reset" value="清除" />


</form>

</body>
</html>


fileupload_control.jsp:

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.io.File"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.util.List"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<%!
int yourMaxMemorySize = 1024 * 1024 * 1024;
File yourTempDirectory = new File("/tmp");
int yourMaxRequestSize = 100 * 1024 * 1024;
boolean writeToFile = true;
String allowedFileTypes = ".txt .pdf .doc .ppt .xls .csv .dbf .gif .jpg .jpeg .png .swf .htm .html .zip .rar";
%>
<%
String saveDirectory = application.getRealPath("/upload");

// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
out.println("isMultipart=" + isMultipart + "<br>");

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(yourMaxMemorySize, yourTempDirectory);

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);

// Set overall request size constraint
upload.setSizeMax(yourMaxRequestSize);

//Create a progress listener
ProgressListener progressListener = new ProgressListener() {
private long megaBytes = -1;

public void update(long pBytesRead, long pContentLength, int pItems) {
long mBytes = pBytesRead / 1000000;
if (megaBytes == mBytes) {
return;
}
megaBytes = mBytes;
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength + " bytes have been read.");
}
}
};
upload.setProgressListener(progressListener);

try {
// Parse the request
List /* FileItem */items = upload.parseRequest(request);

// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();

if (item.isFormField()) {
// Process a regular form field
//processFormField(item);
String name = item.getFieldName();
String value = item.getString("UTF-8");
out.println(name + "=" + value + "<br />");
} else {
// Process a file upload
//processUploadedFile(item);
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
out.println("fieldName=" + fieldName + "<br />");
out.println("fileName=" + fileName + "<br />");
out.println("contentType=" + contentType + "<br />");
out.println("isInMemory=" + isInMemory + "<br />");
out.println("sizeInBytes=" + sizeInBytes + "<br />");
if (fileName != null && !"".equals(fileName)) {
if (writeToFile) {
fileName = FilenameUtils.getName(fileName);
out.println("fileName to be saved=" + fileName + "<br />");
String extension = FilenameUtils.getExtension(fileName);
if (allowedFileTypes.indexOf(extension.toLowerCase()) != -1) {
File uploadedFile = new File(saveDirectory, fileName);
item.write(uploadedFile);
} else {
out.println("上傳的檔案不能是" + extension + "<br />");
}
} else {
//InputStream uploadedStream = item.getInputStream();
//...
//uploadedStream.close();
// Process a file upload in memory
byte[] data = item.get();
out.println("data size=" + data.length + "<br />");
}
}
}
}
} catch (FileUploadBase.SizeLimitExceededException ex1) {
out.println("上傳檔案超過最大檔案允許大小" + yourMaxRequestSize / (1024 * 1024) + "MB !");
}
%>


另外需要在web.xml中加上下列設定:

<web-app>
...
<listener>
<listener-class>
org.apache.commons.fileupload.servlet.FileCleanerCleanup
</listener-class>
</listener>
...
</web-app>

參考資料:
http://commons.apache.org/fileupload/using.html
 Filename fileupload_control.html [Disk] Download
 Description 檔案上傳表單
 Filesize 862 bytes
 Downloaded:  112 time(s)

 Filename fileupload_control.jsp [Disk] Download
 Description 檔案上傳處理程式
 Filesize 4 Kbytes
 Downloaded:  124 time(s)


分享經驗 累積智慧
[WWW]
hannibal0416

十級學員

Joined: 2009/11/24
Messages: 2
Offline
版大您好,請問一下為什麼我會出現這種錯誤
我用tomcat 6.0,win XP sp3 上面的JAR檔也已丟至正確資料夾,
感覺好像是request的問題,麻煩您幫忙解決一下。 感謝

org.apache.jasper.JasperException: An exception occurred processing JSP page /test/fileupload.jsp at line 25

22:
23: // Check that we have a file upload request
24:
25: boolean isMultipart = ServletFileUpload.isMultipartContent(request);
26:
27: out.println("isMultipart="+isMultipart+"<br>");
28:
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
hannibal0416您好:
基本上您給的資訊太少,並不足以判斷問題出在哪裡,可能得請您再花點耐性,把Tomcat的log檔內容看一下,也許就可以找到原因了。

分享經驗 累積智慧
[WWW]
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
由於有網友在問哪段可以取到上傳網頁的檔案說明的欄位的值?簡單說明如下:

上傳網頁的檔案說明的欄位,包在第一個if內,註解有註明是regular form field那段,可以透過欄位名稱比對取得其值:

String fileDesc = null;

...
if (item.isFormField()) {
// Process a regular form field
//processFormField(item);
String name = item.getFieldName();
String value = item.getString("UTF-8");
out.println(name + "=" + value+"
");
if ("filedesc".equals(name)) {
fileDesc = value;
}
} else {
...


另外如果有需要刪除檔案時,可以參考下列的範例(例如要刪除已上傳的檔案)
// Delete a file

public static boolean deleteFile(String filename) {
File f = new File(filename);
boolean result = false;
if (f.exists()) {
result = f.delete();
if (result != true) {
System.out.println("Delete file failed: " + f.getName());
}
}
return result;
}

分享經驗 累積智慧
[WWW]
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
如果一次上傳多個檔案,然後要分別儲存上傳的檔案名稱和說明欄資料,可以參考這個範例。
程式碼:
fileupload_streaming.html:

<html>
<head>
<title>File Upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
</head>
<body>

檔案上傳



<form name="upload" enctype="multipart/form-data" method="post" action="fileupload_streaming.jsp">

上傳檔案: <input type="file" name="file" size="20" maxlength="20">


檔案說明: <input type="text" name="filedesc" size="30" maxlength="50">


上傳檔案: <input type="file" name="file" size="20" maxlength="20">


檔案說明: <input type="text" name="filedesc" size="30" maxlength="50">


<input type="submit"value="上傳"> <input type="reset" value="清除">


</form>

</body>
</html>


fileupload_streaming.jsp:

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.fileupload.util.Streams"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<%
String saveDirectory = application.getRealPath("/upload");

// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
out.println("isMultipart="+isMultipart+"<br>");

// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();

//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
private long megaBytes = -1;
public void update(long pBytesRead, long pContentLength, int pItems) {
long mBytes = pBytesRead / 1000000;
if (megaBytes == mBytes) {
return;
}
megaBytes = mBytes;
System.out.println("We are currently reading item " + pItems);
if (pContentLength == -1) {
System.out.println("So far, " + pBytesRead + " bytes have been read.");
} else {
System.out.println("So far, " + pBytesRead + " of " + pContentLength
+ " bytes have been read.");
}
}
};
upload.setProgressListener(progressListener);

// Parse the request
List<String> fileDescList = new ArrayList<String>();
List<String> fileNameList = new ArrayList<String>();
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
String value = Streams.asString(stream);
out.println(name + "=" + value+"
");
if ("filedesc".equals(name)) {
fileDescList.add(value);
}
} else {
System.out.println("File field " + name + " with file name "
+ item.getName() + " detected.");
// Process the input stream
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
out.println("fieldName="+fieldName+"
");
out.println("fileName="+fileName+"
");
out.println("contentType="+contentType+"
");
if (fileName != null && !"".equals(fileName)) {
fileName= FilenameUtils.getName(fileName);
out.println("fileName saved="+fileName+"
");
fileNameList.add(fileName);
File uploadedFile = new File(saveDirectory, fileName);
FileOutputStream uploadedFileStream =
new FileOutputStream(uploadedFile);
Streams.copy(stream, uploadedFileStream, true);
}
}
}
for (int i = 0; i < fileNameList.size(); i++) {
String fileDesc = fileDescList.get(i);
String fileName = fileNameList.get(i);
out.println(fileName+":"+fileDesc+"
");
// save to database for future use
}
%>
 Filename fileupload_streaming.jsp [Disk] Download
 Description Multiple file upload fields handler
 Filesize 3 Kbytes
 Downloaded:  74 time(s)

 Filename fileupload_streaming.html [Disk] Download
 Description Multiple file upload fields form
 Filesize 699 bytes
 Downloaded:  93 time(s)


分享經驗 累積智慧
[WWW]
victer0327

十級學員

Joined: 2010/1/8
Messages: 3
Offline
請問板大,檔案上傳時的說明(filedesc)輸入中文會出現亂碼,這該如何解決呢??
A-man

十級學員

Joined: 2010/1/14
Messages: 3
Offline
感謝版大的分享,

本人是jsp, java 新手,
剛剛正想在功課加上上傳的功能 , 搜尋之下 , 找到你的主題, 我真的太幸運了 ^^

在網上找了一下, 找不到明確的方法,
所以想問問 安裝函式庫 該怎安裝 ?

我正使用eclipse + tomcat 4.1

在Apache Commons的網站我下載了
commons-io-1.4-src.zip & commons-fileupload-1.2.1-src.zip

解壓後 發現內有很多不同的檔案,

我是應該把以下兩個目錄個的檔案, 全部複製到我eclipse 的Project 內 ?
commons-fileupload-1.2.1-src\src\java\org

commons-io-1.4-src\src\java\org\


謝謝你 ^^
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
victer0327 wrote:請問板大,檔案上傳時的說明(filedesc)輸入中文會出現亂碼,這該如何解決呢??

試著自己找答案看看,一般通常就是編碼的問題,可以查查看API中有沒有和原來使用的method同樣名稱,但多了一個encoding之類的參數的method。
API的網址如下:
http://commons.apache.org/fileupload/apidocs/index.html

在Streams類別中有個asString 的method,描述如下:
static java.lang.String asString(java.io.InputStream pStream, java.lang.String pEncoding)
This convenience method allows to read a FileItemStream's content into a string, using the given character encoding.

試著把原來的程式中的
String value = Streams.asString(stream);

改為
String encoding = "UTF-8";

String value = Streams.asString(stream, encoding);

看看,如果不行再依序調整encoding的值為"Big5", "MS950", "ISO-8859-1", ...

分享經驗 累積智慧
[WWW]
andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
A-man wrote:
在網上找了一下, 找不到明確的方法,
所以想問問 安裝函式庫 該怎安裝 ?

我正使用eclipse + tomcat 4.1

在Apache Commons的網站我下載了
commons-io-1.4-src.zip & commons-fileupload-1.2.1-src.zip

解壓後 發現內有很多不同的檔案,

我是應該把以下兩個目錄個的檔案, 全部複製到我eclipse 的Project 內 ?
commons-fileupload-1.2.1-src\src\java\org

commons-io-1.4-src\src\java\org\


謝謝你 ^^

A-man您應該只需要放jar檔到lib目錄下就好,去下載binary的版本吧!

分享經驗 累積智慧
[WWW]
A-man

十級學員

Joined: 2010/1/14
Messages: 3
Offline
嘗試把jar檔加入IDE 和 直接將 java source放進去 ,
上傳能正確運作, 不過在兩個class發現錯誤

如下圖, class 內有數個相同的Error

我使用的是 j2sdk-1_4_2_17 & apache-tomcat-4.1.40

會不會是因為java 的version問題 ?
[Thumb - problem.JPG]
 Filename problem.JPG [Disk] Download
 Description No description given
 Filesize 144 Kbytes
 Downloaded:  33 time(s)

andowson

七段學員
[Avatar]

Joined: 2007/1/2
Messages: 710
Location: 台北
Offline
A-man您好:
您可以參考這個網址下載相依性的jar檔
http://commons.apache.org/fileupload/dependencies.html

分享經驗 累積智慧
[WWW]
A-man

十級學員

Joined: 2010/1/14
Messages: 3
Offline
To andowson:

感謝你的幫忙, 問題解決了, 謝謝
lionsgogo

十級學員

Joined: 2010/3/7
Messages: 3
Offline
org.apache.jasper.JasperException: Exception in JSP: /fileupload.jsp:74

71: fileName= FilenameUtils.getName(fileName);
72: out.println("fileName saved="+fileName+"<br>");
73: File uploadedFile = new File(saveDirectory, fileName);
74: item.write(uploadedFile);
75: }
76: }
77: }

為什麼會有錯誤??
 
Forum Index » 網頁程式設計 Web Development
Go to:   
Mobile view