本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!
上一篇:
Struts1.x系列教程(8):上傳單個(gè)文件
Struts2教程7:上傳任意多個(gè)文件
從《Struts1.x系列教程(8):上傳單個(gè)文件》中給出的例子可以看出,在Struts1.x中上傳單個(gè)文件是非常簡(jiǎn)單的,但在實(shí)際應(yīng)用中,上傳文件的個(gè)數(shù)一般是不確定的,如在網(wǎng)絡(luò)硬盤(pán)中,用戶(hù)可以根據(jù)自己的需要上傳任意多個(gè)文件(當(dāng)然,網(wǎng)絡(luò)硬盤(pán)一次上傳文件的數(shù)目一般也是有上限的,如50個(gè),但用戶(hù)可以只上傳了3個(gè)文件,因此,在這種情況下,上傳文件的個(gè)數(shù)也是不確定的)。如果讀者用過(guò)“網(wǎng)易網(wǎng)盤(pán)”或其他類(lèi)似的服務(wù)程序,它們的上傳文件功能基本上都是根據(jù)用戶(hù)選擇的文件多少來(lái)添加要上傳的文件(并不是一開(kāi)始就在界面上放很多<input type=’file’>元素來(lái)讓用戶(hù)輸入上傳文件名)。為了讓讀者也可以使用Struts來(lái)實(shí)現(xiàn)這個(gè)功能,在本節(jié)將給出一個(gè)用Struts實(shí)現(xiàn)的類(lèi)似“網(wǎng)易網(wǎng)盤(pán)”的上傳任意多個(gè)文件的Web程序。在實(shí)現(xiàn)Web程序之前,讓我們先看看圖1所示的主頁(yè)面。
圖1
在本程序中,用戶(hù)通過(guò)在文本框中輸入本地文件名或使用“瀏覽”按鈕選擇要上傳的文件后,就會(huì)在界面的下方添加這個(gè)被錄入的文件名,如果錄入有誤,或是不想上傳某個(gè)文件,可以使用“刪除”功能將當(dāng)前文件刪除。在確認(rèn)正確錄入所有的上傳文件后,使用“上傳”按鈕開(kāi)始上傳文件。
實(shí)現(xiàn)這個(gè)Web程序的基本步驟和《Struts1.x系列教程(8):上傳單個(gè)文件》一文中所給出的例子類(lèi)似,我們可按下面五步來(lái)實(shí)現(xiàn)這個(gè)Web程序:
【第1步】建立上傳文件的JSP頁(yè)面
要想實(shí)現(xiàn)上述的功能,需要在JavaScript中使用DOM技術(shù)(關(guān)于JavaScript和DOM技術(shù)的相關(guān)內(nèi)容已經(jīng)超出本文討論的范圍,如果讀者想了解JavaScript和DOM技術(shù)的細(xì)節(jié)部分,請(qǐng)參閱其他相關(guān)技術(shù)資料)。
在<samples工程目錄>目錄中建立一個(gè)uploadMoreFile.jsp文件,代碼如下:
<%@ page pageEncoding="GBK"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>上傳任意多個(gè)文件(總大小不能超過(guò)2M)</title>
<script language="javascript">
// 在DOM中插入一個(gè)上傳文件列表項(xiàng)(div元素)和一個(gè)<input type="file"/>元素
function insertNextFile(obj)
{
// 獲取上傳控制個(gè)數(shù)
var childnum = document.getElementById("files").getElementsByTagName("input").length;
var id = childnum - 1;
var fullName = obj.value;
// 插入<div>元素及其子元素
var fileHtml = '';
fileHtml += '<div id = "file_preview' + id + '" style ="border-bottom: 1px solid #CCC;">';
fileHtml += '<img width =30 height = 30 src ="images/file.gif" title="' + fullName + '"/>';
fileHtml += '<a href="javascript:;" onclick="removeFile(' + id + ');">刪除</a> ';
fileHtml += fullName.substr(fullName.lastIndexOf('\\')+1) +' </div>';
var fileElement = document.getElementById("files_preview");
fileElement.innerHTML = fileElement.innerHTML + fileHtml;
obj.style.display = 'none'; // 隱藏當(dāng)前的<input type=”file”/>元素
addUploadFile(childnum); // 插入新的<input type=”file”/>元素
}
// 插入新的<input type=”file”/>元素,適合于不同的瀏覽器(包括IE、FireFox等)
function addUploadFile(index)
{
try // 用于IE瀏覽器
{
var uploadHTML = document.createElement( "<input type='file' id='file_" + index +
"' name='file[" + index + "]' onchange='insertNextFile(this)'/>");
document.getElementById("files").appendChild(uploadHTML);
}
catch(e) // 用于其他瀏覽器
{
var uploadObj = document.createElement("input");
uploadObj.setAttribute("name", "file[" + index + "]");
uploadObj.setAttribute("onchange", "insertNextFile(this)");
uploadObj.setAttribute("type", "file");
uploadObj.setAttribute("id", "file_" + index);
document.getElementById("files").appendChild(uploadObj);
}
}
function removeFile(index) // 刪除當(dāng)前文件的<div>和<input type=”file”/>元素
{
document.getElementById("files_preview").removeChild(document.getElementById("file_preview" + index));
document.getElementById("files").removeChild(document.getElementById("file_" + index));
}
function showStatus(obj) // 顯示“正在上傳文件
”提示信息
{
document.getElementById("status").style.visibility="visible";
}
</script>
</head>
<body>
<html:form enctype="multipart/form-data" action="uploadMoreFile">
<span id="files"> <%-- 在此處插入用于上傳文件的input元素 --%>
<input type="file" id="file_0" name="file[0]" onchange="insertNextFile(this)" />
</span>
<html:submit value=" 上傳 " onclick="showStatus(this);"/>
</html:form> <p>
<div id ="status" style="visibility:hidden;color:Red">正在上傳文件
</div> <p>
<%-- 在此處用DOM技術(shù)插入上傳文件列表項(xiàng) --%>
<div id="files_preview" style ="width:500px;height:500px; overflow :auto" ></div>
</body>
</html>
在uploadMoreFile.jsp文件中使用了JavaScript和DOM技術(shù)來(lái)控制新加入的上傳文件以及刪除不需要的上傳文件。并且在加入<input type=”file”/>元素時(shí)考慮了不同的瀏覽器的差異(詳見(jiàn)addUploadFile)。
【第2步】建立ActionForm的子類(lèi)
在<samples工程目錄>\src\actionform目錄中建立一個(gè)UploadMoreForm.java文件,代碼如下:
package actionform;
import org.apache.struts.action.*;
import org.apache.struts.upload.FormFile;
import java.util.*;
public class UploadMoreForm extends ActionForm
{
private List<FormFile> myFiles = new ArrayList<FormFile>(); // 用于保存不定數(shù)量的FormFile對(duì)象
public FormFile getFile(int i) // 索引屬性
{
return myFiles.get(i);
}
public void setFile(int i, FormFile myFile) // 索引屬性
{
if (myFile.getFileSize() > 0) // 只有上傳文件的字節(jié)數(shù)大于0,才上傳這個(gè)文件
{
myFiles.add(myFile);
}
}
public int getFileCount() // 獲得上傳文件的個(gè)數(shù)
{
return myFiles.size();
}
}
在UploadMoreFile類(lèi)中使用了List對(duì)象來(lái)保存不定數(shù)量的FormFile對(duì)象。讀者也可以使用其他的集合類(lèi)來(lái)保存這些FormFile對(duì)象。而且在UploadMoreFile類(lèi)中使用了帶索引的屬性,詳見(jiàn)getFile和setFile方法。在這兩個(gè)方法中,第一個(gè)參數(shù)是一個(gè)int類(lèi)型的變量。要注意的是,索引屬性的get和set方法的第一個(gè)參數(shù)必須是int類(lèi)型的變量,否則系統(tǒng)會(huì)不認(rèn)這個(gè)索引屬性。這個(gè)索引屬性用于和客戶(hù)端不定數(shù)量的<input type=”file” />元素相對(duì)應(yīng),每一個(gè)索引項(xiàng)代表一個(gè)<input type=”file” />元素上傳的文件(FormFile對(duì)象)。
【第3步】建立Struts動(dòng)作類(lèi)(Action的子類(lèi))
由于在《Struts1.x系列教程(8):上傳單個(gè)文件》一文的例子中的UploadAction類(lèi)中已經(jīng)有了一個(gè)saveFile方法用于保存單個(gè)上傳文件,因此,處理多個(gè)上傳文件的Struts動(dòng)作類(lèi)可以從UploadAction類(lèi)繼承。在<samples工程目錄>\src\action目錄中建立一個(gè)UploadMoreAction.java文件,代碼如下:
package action;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.upload.FormFile;
import java.io.*;
import actionform.*;
public class UploadMoreAction extends UploadAction
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
{
UploadMoreForm umForm = (UploadMoreForm) form;
PrintWriter out = null;
int count = 0;
try
{
response.setCharacterEncoding("GBK");
out = response.getWriter();
count = umForm.getFileCount(); // 獲得上傳文件的總數(shù)
for (int i = 0; i < count; i++)
{
saveFile(umForm.getFile(i)); // 開(kāi)始保存每一個(gè)上傳文件
}
out.println("成功上傳" + String.valueOf(count) + "個(gè)文件.");
}
catch (Exception e)
{
out.println(e.getMessage());
}
return null;
}
}
【第4步】配置struts-config.xml
在這一步來(lái)配置一下在第2步和第3步分別建立的ActionForm和Action的子類(lèi)。打開(kāi)struts-config.xml文件,在<form-beans>元素中加入如下的子元素:
<form-bean name="uploadMoreForm" type="actionform.UploadMoreForm" />
在<action-mappings>元素中加入如下的子元素:
<action name="uploadMoreForm" path="/uploadMoreFile" scope="request" type="action.UploadMoreAction" />
【第5步】復(fù)制gif圖片
本例中使用了一個(gè)gif圖,在Web根目錄中建立一個(gè)images目錄,并復(fù)制一個(gè)file.gif文件(30*30)到這個(gè)目錄(讀者可以使用自己喜歡的任何gif圖片)。
由于在《Struts1.x系列教程(8):上傳單個(gè)文件》一文的例子中已經(jīng)設(shè)置了上傳文件的保存路徑和上傳文件的大小限制,因此,在本例中仍然使用這一設(shè)置。但要注意的是,在上傳多個(gè)文件時(shí),最大上傳文件尺寸指的是所有上傳文件的尺寸之和,而不是指每個(gè)文件的尺寸。
啟動(dòng)Tomcat后,在IE地址欄中輸入如下的URL來(lái)測(cè)試程序:
http://localhost:8080/samples/uploadMoreFile.jsp
下一篇:
Struts1.x系列教程(10):Validator驗(yàn)證框架入門(mén)
新浪微博:http://t.sina.com.cn/androidguy 昵稱(chēng):李寧_Lining