實務上檔案上傳數量不固定(如網路硬碟)。本文結合 Struts FormFile 索引屬性與 JavaScript DOM 動態增減 <input type="file"> 元素,實作類似「網易網盤」的多檔上傳介面。
List<FormFile> 儲存不定數量檔案,以索引屬性 getFile(int)/setFile(int, FormFile) 綁定。FormFile。var childnum = document.getElementById("files").getElementsByTagName("input").length;
var id = childnum - 1;
// 插入預覽區 div(含檔名、刪除鈕)
var fileHtml = '<div id="file_preview' + id + '" style="border-bottom:1px solid #CCC">'
+ '<img src="images/file.gif" width=30 height=30 title="' + fullName + '"/>'
+ '<a href="javascript:;" onclick="removeFile(' + id + ');">刪除</a> '
+ fullName.substr(fullName.lastIndexOf('\\\\')+1) + '</div>';
document.getElementById("files_preview").innerHTML += fileHtml;
// 隱藏當前 file input,動態新增下一個
obj.style.display = 'none';
addUploadFile(childnum); // 跨瀏覽器建立新 input[type=file]
function addUploadFile(index) {
try { // IE
var el = document.createElement("<input type='file' id='file_" + index
+ "' name='file[" + index + "]' onchange='insertNextFile(this)'/>");
document.getElementById("files").appendChild(el);
} catch(e) { // Firefox/Chrome
var el = document.createElement("input");
el.setAttribute("name", "file[" + index + "]");
el.setAttribute("onchange", "insertNextFile(this)");
el.setAttribute("type", "file");
el.setAttribute("id", "file_" + index);
document.getElementById("files").appendChild(el);
}
}
function removeFile(index) {
document.getElementById("files_preview").removeChild(document.getElementById("file_preview" + index));
document.getElementById("files").removeChild(document.getElementById("file_" + index));
}
package actionform;
import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;
import java.util.*;
public class UploadMoreForm extends ActionForm {
private List<FormFile> myFiles = new ArrayList<FormFile>();
public FormFile getFile(int i) { return myFiles.get(i); } // 索引 getter
public void setFile(int i, FormFile f) { // 索引 setter
if (f.getFileSize() > 0) myFiles.add(f); // 忽略空檔案
}
public int getFileCount() { return myFiles.size(); }
}
關鍵:索引屬性首參數必須為 int,Struts 自動將同名 file[0]、file[1]... 綁定至 setFile(0, ...)、setFile(1, ...)。
package action;
import actionform.UploadMoreForm;
import org.apache.struts.upload.FormFile;
public class UploadMoreAction extends UploadAction { // 繼承單檔上傳 Action
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UploadMoreForm uf = (UploadMoreForm) form;
int count = uf.getFileCount();
for (int i = 0; i < count; i++) {
saveFile(uf.getFile(i)); // 父類別方法儲存單檔
}
response.getWriter().println("成功上傳 " + count + " 個檔案.");
return null;
}
}
struts-config.xml:<action name="uploadMoreForm" path="/uploadMoreFile" type="action.UploadMoreAction" />web.xml:設定 uploadPath 初始化參數(同單檔上傳)。<controller maxFileSize="2M"/>:**限制所有上傳檔案總大小**,非單檔大小。images/file.gif (30x30) 作為預覽圖示。訪問 https://localhost:8080/samples/uploadMoreFile.jsp,可動態新增/刪除檔案,點擊上傳後顯示成功筆數。
此範例展示 Struts 索引屬性綁定動態表單欄位的標準模式,配合前端 DOM 操作實現靈活的多檔上傳體驗,是 Struts 1.x 時代處理不定數量檔案上傳的經典做法。