Struts2的多文件上传并不是一个难点,但是如果想实现带有上传文件进度条的功能就必须借鉴一些工具,FileFlashUpload组件是一个不错的选择。
本人在开发实际项目中突然使用到了Struts2的文件上传,为了达到界面的友好性想使用一种带有上传进度条的文件上传工具,但是靠自己编码来实现有点困难,于是在网上查找了大量的资料,偶然发现了FileFlashUpload这个文件上传工具,于是借鉴了很多网上朋友的开发实例,加上自己的研究改动,实现了Struts2+FileFlashUpload的文件上传,下面先上代码,关键部分以及一些重点问题稍后讲解。
首先是
FileAction代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.tjuci_net.entity.Knowledgebase;
import com.tjuci_net.entity.KnowledgebaseType;
import com.tjuci_net.service.KnowledgebaseTypeService;
import com.tjuci_net.web.action.common.BaseAction;
/**
* 处理文件上传的Action
*
*/
public class FileAction extends BaseAction {
//////////////////////文件上传时需要的属性////////////////////////
private List<File> Filedata; //代表文件的内容 (这个是非常重要的,因为FileFlashUpload向action传递的是通过Filedata实现)
private List<String> FiledataFileName; //代表文件的名称
private List<String> FiledataContentType; //代表文件的MIME类型
public String upload() throws Exception{
for(int i=0;i<Filedata.size();i++){
//System.out.println("上传的文件名是:" + FiledataFileName.get(i));
//System.out.println("上传的文件类型是:" + FiledataContentType.get(i));
//System.out.println("上传的文件大小:" + Filedata.get(i).length());
//System.out.println("Struts2处理文件上传是的临时名称:" + Filedata.get(i).getName());
//获取存放上传文件的目录的真实路径,我存放的路径是files的目录下
String basePath = ServletActionContext.getServletContext().getRealPath("/files")+FiledataFileName.get(i);
File destFile = new File(basePath, FiledataFileName.get(i));
//实现文件的上传
FileUtils.copyFile(Filedata.get(i), destFile);
}
return SUCCESS;
}
public List<File> getFiledata() {
return Filedata;
}
public void setFiledata(List<File> filedata) {
Filedata = filedata;
}
public List<String> getFiledataFileName() {
return FiledataFileName;
}
public void setFiledataFileName(List<String> filedataFileName) {
FiledataFileName = filedataFileName;
}
public List<String> getFiledataContentType() {
return FiledataContentType;
}
public void setFiledataContentType(List<String> filedataContentType) {
FiledataContentType = filedataContentType;
}
}
Struts.xml配置
<action name="upload" class="com.web.action.FileAction">
<result>/succ.jsp</result>
<result name="input">/input.jsp</result>
<!--定义上传文件的大小,格式-->
<interceptor-ref name="fileUpload">
<param name="maximumSize">4073741824</param><!-- maxinumSize: 4G -->
<param name="allowedTypes">image/png,image/gif,image/jpeg,image/jpg,image/x-png,application/zip,application/rar,application/octet-stream</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
页面fileUpload.jsp代码
<%@ page pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!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>文件上传</title>
</head>
<body >
<fieldset style="background: #ccc">
<!-- 使用FlashFileUpload.swf 上传文件,文件类型:*jpg(可自行更改),文件大小: 4G-->
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0"
width="100%" height="800" id="file" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<!--添加你的FileFlashUpload所在的目录-->
<param name="movie" value="${ctx}/flash/FlashFileUpload_en.swf?ver=2009041702" />
<param name="quality" value="high" />
<param name="wmode" value="transparent">
<!--定义你的上传文件的格式以及action的名称-->
<param name="FlashVars"value='fileTypeDescription=文&fileTypes=*.jpg;&fileSizeLimit=4073741824&totalUploadSize=4073741824&uploadPage=./file_upload.action;'>
<!--添加你的FileFlashUpload所在的目录,再次定义上传文件的格式和action的名称-->
<embed src="${ctx}/flash/FlashFileUpload_en.swf?ver=2009041702"FlashVars='fileTypeDescription=文件&fileTypes=*jpg;&fileSizeLimit=4073741824&totalUploadSize=4073741824&uploadPage=./file_upload.action;'quality="high" wmode="transparent" width="100%" height="800"name="file" align="middle" allowscriptaccess="sameDomain"type="application/x-shockwave-flash"pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</fieldset>
</body>
</html>
以上就是这主要的三个部分,只要根据自己的需要进行配置就可以实现文件上传的功能,上传文件的目录是你的服务器上面的文件夹中,并不是Myeclipse或者Eclipse的WebRoot目录下。上面的注释也很详细了,相信大家只改小部分就可以实现了。
下面说一下我们在使用FileFlashUpload中所遇到的问题:首先FileFlashUpload使用的是flash进行文件的大部分操作,官方只给出了少量的关于PHP连接的用法,通过界面上我们可以达到文件批量上传这种很直观的效果,但是实际上这个组件是每上传一个文件就需要调用一次Struts2的upload.action,只是组件隐藏了这种方式,使得我们很难想象其中的方法。另外,使用FileFlashUpload上传时大家往往想通过request、session等会话方式返回一些数据或者传递数据,但是这里本人要重点强调的是:这种方法使用FileFlashUpload基本无法实现,因为当你使用这个组件时,flash会重新开启一个会话,并不是当前的会话,所以数据很难通过request、session等传递,如果实在想获取的话可以或得当先会话的session_id然后再进行相关操作。如果是单一想实现文件上传功能的话,并且将单个文件的路径存储到数据库中的话,使用FileFlashUpload是个很不错的选择。
好了,就写到这里了,希望会对大家有多帮助,本人也是参考了网上大神们的大量文章,如果有什么不对的地方恳请大家批评指正,共同学习,共同分享,共同进步。