上一篇: Struts1.x系列教程(8):上传单个文件
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="ProgId" content="Word.Document"> <meta name="Generator" content="Microsoft Word 11"> <meta name="Originator" content="Microsoft Word 11"> <link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"> <!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --> </style> <!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} </style> <![endif]--> Struts2教程7:上传任意多个文件
从 《Struts1.x系列教程(8):上传单个文件》 中给出的例子可以看出,在 Struts1.x 中上传单个文件是非常简单的,但在实际应用中,上传文件的个数一般是不确定的,如在网络硬盘中,用户可以根据自己的需要上传任意多个文件(当然,网络硬盘一次上传文件的数目一般也是有上限的,如 50 个,但用户可以只上传了 3 个文件,因此,在这种情况下,上传文件的个数也是不确定的)。如果读者用过“网易网盘”或其他类似的服务程序,它们的上传文件功能基本上都是根据用户选择的文件多少来添加要上传的文件(并不是一开始就在界面上放很多 <input type=’file’> 元素来让用户输入上传文件名)。为了让读者也可以使用 Struts 来实现这个功能,在本节将给出一个用 Struts 实现的类似“网易网盘”的上传任意多个文件的 Web 程序。在实现 Web 程序之前,让我们先看看图 1 所示的主页面。

图1
在本程序中,用户通过在文本框中输入本地文件名或使用“浏览”按钮选择要上传的文件后,就会在界面的下方添加这个被录入的文件名,如果录入有误,或是不想上传某个文件,可以使用“删除”功能将当前文件删除。在确认正确录入所有的上传文件后,使用“上传”按钮开始上传文件。
实现这个
Web
程序的基本步骤和
《Struts1.x系列教程(8):上传单个文件》
一文中
所给出的例子类似,我们可按下面五步来实现这个
Web
程序:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} </style> <![endif]-->
【第
1
步】
建立上传文件的
JSP
页面
要想实现上述的功能,需要在
JavaScript
中使用
DOM
技术(关于
JavaScript
和
DOM
技术的相关内容已经超出本文讨论的范围,如果读者想了解
JavaScript
和
DOM
技术的细节部分,请参阅其他相关技术资料)。
在<samples工程目录>目录中建立一个uploadMoreFile.jsp文件,代码如下:
<% @tagliburi = " http://struts.apache.org/tags-html " prefix = " html " %>
< html >
< head >
< title > 上传任意多个文件(总大小不能超过2M) </ title >
< script language ="javascript" >
// 在DOM中插入一个上传文件列表项(div元素)和一个<inputtype="file"/>元素
function insertNextFile(obj)
{
// 获取上传控制个数
var childnum = document.getElementById( " files " ).getElementsByTagName( " input " ).length;
var id = childnum - 1 ;
var fullName = obj.value;
// 插入<div>元素及其子元素
var fileHtml = '';
fileHtml += ' < divid = " file_preview'+id+' " style = " border-bottom:1pxsolid#CCC; " > ';
fileHtml += ' < imgwidth = 30 height = 30 src = " images/file.gif " title = " '+fullName+' " /> ';
fileHtml += ' < ahref = " javascript:; " onclick = " removeFile('+id+'); " > 删除 </ a > & nbsp; & nbsp;';
fileHtml += fullName.substr(fullName.lastIndexOf('\\') + 1 ) + ' </ div > ';
var fileElement = document.getElementById( " files_preview " );
fileElement.innerHTML = fileElement.innerHTML + fileHtml;
obj.style.display = 'none'; // 隐藏当前的<inputtype=”file”/>元素
addUploadFile(childnum); // 插入新的<inputtype=”file”/>元素
}
// 插入新的<inputtype=”file”/>元素,适合于不同的浏览器(包括IE、FireFox等)
function addUploadFile(index)
{
try // 用于IE浏览器
{
var uploadHTML = document.createElement( " <inputtype='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) // 删除当前文件的<div>和<inputtype=”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" > 正在上传文件

<% -- 在此处用DOM技术插入上传文件列表项 -- %>
< div id ="files_preview" style ="width:500px;height:500px;overflow:auto" ></ div >
</ body >
</ html >
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} </style> <![endif]-->
在
uploadMoreFile.jsp
文件中使用了
JavaScript
和
DOM
技术来控制新加入的上传文件以及删除不需要的上传文件。并且在加入
<input type=”file”/>
元素时考虑了不同的浏览器的差异(详见
addUploadFile
)。
【第
2
步】
建立
ActionForm
的子类
在
<samples
工程目录
>\src\actionform
目录中建立一个
UploadMoreForm.java
文件,代码如下:
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 > (); // 用于保存不定数量的FormFile对象
public FormFilegetFile( int i) // 索引属性
{
return myFiles.get(i);
}
public void setFile( int i,FormFilemyFile) // 索引属性
{
if (myFile.getFileSize() > 0 ) // 只有上传文件的字节数大于0,才上传这个文件
{
myFiles.add(myFile);
}
}
public int getFileCount() // 获得上传文件的个数
{
return myFiles.size();
}
}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} </style> <![endif]-->
在
UploadMoreFile
类中使用了
List
对象来保存不定数量的
FormFile
对象。读者也可以使用其他的集合类来保存这些
FormFile
对象。而且在
UploadMoreFile
类中使用了带索引的属性,详见
getFile
和
setFile
方法。在这两个方法中,第一个参数是一个
int
类型的变量。要注意的是,索引属性的
get
和
set
方法的第一个参数必须是
int
类型的变量,否则系统会不认这个索引属性。这个索引属性用于和客户端不定数量的
<input type=”file” />
元素相对应,每一个索引项代表一个
<input type=”file” />
元素上传的文件(
FormFile
对象)。
【第
3
步】
建立
Struts
动作类
(Action
的子类
)
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} </style> <![endif]-->
由于在
《Struts1.x系列教程(8):上传单个文件》
一文
的例子中
的
UploadAction
类中已经有了一个
saveFile
方法用于保存单个上传文件,因此,处理多个上传文件的
Struts
动作类可以从
UploadAction
类继承。在
<samples
工程目录
>\src\action
目录中建立一个
UploadMoreAction.java
文件,代码如下:
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 ActionForwardexecute(ActionMappingmapping,ActionFormform,
HttpServletRequestrequest,HttpServletResponseresponse)
{
UploadMoreFormumForm = (UploadMoreForm)form;
PrintWriterout = null ;
int count = 0 ;
try
{
response.setCharacterEncoding( " GBK " );
out = response.getWriter();
count = umForm.getFileCount(); // 获得上传文件的总数
for ( int i = 0 ;i < count;i ++ )
{
saveFile(umForm.getFile(i)); // 开始保存每一个上传文件
}
out.println( " 成功上传 " + String.valueOf(count) + " 个文件. " );
}
catch (Exceptione)
{
out.println(e.getMessage());
}
return null ;
}
}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman";} </style> <![endif]-->
【第
4
步】
配置
struts-config.xml
在这一步来配置一下在第2步和第3步分别建立的ActionForm和Action的子类。打开struts-config.xml文件,在<form-beans>元素中加入如下的子元素:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 在<action-mappings>元素中加入如下的子元素:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><!--[if gte mso 9]><xml> Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt;} div.Section1 {page:Section1;} --></style> 【第 5 步】 复制 gif 图片
本例中使用了一个
gif
图,在
Web
根目录中建立一个
images
目录,并复制一个
file.gif
文件(
30*30
)到这个目录(读者可以使用自己喜欢的任何
gif
图片)。
由于在
《Struts1.x系列教程(8):上传单个文件》
一文
的例子中已经设置了上传文件的保存路径和上传文件的大小限制,因此,在本例中仍然使用这一设置。但要注意的是,在上传多个文件时,最大上传文件尺寸指的是所有上传文件的尺寸之和,而不是指每个文件的尺寸。
http://localhost:8080/samples/uploadMoreFile.jsp
下一篇: Struts1.x系列教程(10):Validator验证框架入门
国内最棒的Google Android技术社区(eoeandroid),欢迎访问!
《银河系列原创教程》 发布
《Java Web开发速学宝典》 出版,欢迎定购