前段时间公司项目中需要做一个酷似163网盘功能的一个文件资源中心的东西,其中涉及到struts批量上传文件的功能,下边总结一下。
第一步,前台实现。前台选择文件功能使用了在网上流传已久的“仿163网盘无刷新上传”的一个js控件,这个控件有针对jsp上传的版本,配置起来也比较简单。google一下就可以找到,如果懒得找也可以ripflowers@gmail.com给我,我会尽快发给你。jsp上的form我使用了“hmtl:form”,用普通的form好像传不到服务器,这里我也有一点疑问,经刘兄提醒应该是普通的form下面的type=”file”不能转换成Struts中的FormFile,关于这个问题以后再研究。

<!--jsp上的form,这里一定要设置“enctype”-->
<html:form action="upload.do?method=upload"  
	method="post" enctype="multipart/form-data>

关于前台的实现就不再废话了,整体实现的效果如下:
upload
第二步,跟前台选择的文件对应的应该要有一个ActionForm,ActionFrom中要放置一个存放FormFile的集合,这样才能够实现文件的批量上传。ActionForm内容如下:

public class BatchUploadForm extends ActionForm {
	private FormFile file;
	// 多附件上传这里应该是一个集合,所以这里用了List
	private List<FormFile> myFiles;
	public BatchUploadForm() {
		myFiles = new ArrayList<FormFile>();
		// 为了能够在页面初始显示一个file
		myFiles.ADD(file);
	}
	public List<FormFile> getMyFiles() {
		RETURN myFiles;
	}
	public void setMyFiles(List<FormFile> myFiles) {
		this.myFiles = myFiles;
	}
	public FormFile getFile() {
		RETURN file;
	}
	public void setFile(FormFile) {
		this.file = file;
	}
}

第三步,设置struts的配置文件,我的配置文件内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config SYSTEM "../struts-config_1_2.dtd">
<struts-config>
	<form-beans>
	    <!--这里配置的Form替换成你的package-->
		<form-bean name="batchUploadForm" type="BatchUploadForm">
	</form-beans>
 
	<action-mappings>
		<!--这里要替换成你的Aciton和你的Forward,
		                      batchUploadForm一定要配置,
		                      既第二步中的ActionForm-->
		<action path="/upload" type="ResourceAction"				 name="batchUploadForm"
			 parameter="method" 
			 scope="request">
			<forward name="success" path=""/>
		</action>
	</action-mappings>
</struts-config>

花开两朵,咱各表一枝,所有的准备工作已经做的差不多了,接下来我们来看Action中的写法,Action中接收文件的方法是敝人从网上抄来的,还没有来得及更深入的理解,先贴出来看,朋友们有什么高见尽管提出来。
第四步,Action中upload方法的实现。

// 文件上传
public ActionForward upload(ActionMapping mapping, ActionForm form,
		HttpServletRequest request, HttpServletResponse response)
		throws Exception {
 
	BatchUploadForm uploadForm = (BatchUploadForm) form;
	// 这里是你文件上传的目标地址
	String uploadPath = "";
	/*
	 * 从Form中得到所有文件类型的元素, 返回的是一个Hashtable
	 */
	Hashtable files = uploadForm.getMultipartRequestHandler()
	.getFileElements();
	// 循环得到所有的FormFile
	FOR (Map.Entry<String, FormFile> entry : 
		(Set<Map.Entry<String, FormFile>>) (files.entrySet())) {
		FormFile ff = entry.getValue();
		/*
		 * 这里的Files是我的一个实体bean 用来存储文件的路径等信息
		 */
		Files file = new Files();
		String fileName = ff.getFileName();
		IF (StringUtils.isBlank(fileName)) {
			continue;
		} else {
			/*
			 * 为避免上传的文件重名, 这里给文件生成随机的名称
			 */
			String objId = UUID.randomUUID().toString();
			// 得到文件的扩展名
			String extendName = fileName.substring(fileName
			.lastIndexOf(".") + 1);
			uploadPath += "/" + objId + "." + extendName;
			BufferedOutputStream outStream = new BufferedOutputStream(
			new FileOutputStream(uploadPath));
			BufferedInputStream inputStream = new BufferedInputStream(ff
			.getInputStream());
			/*
			 * 这里的FileUtil是一个将文件流写到硬盘 的一个工具类,内容见下
			 */
			// 保存文件到服务器
			FileUtil.createFile(inputStream, outStream);
			/**
			 * 关于文件的基本信息 这里已经全部可以获取了, 怎么样保存就看你了!
			 */
		}
	}
 
	RETURN NULL;
}

最后把FileUtil这个简单的工具类贴出来。

public class FileUtil {
	public static void createFile(InputStream IN, 
                                              OutputStream out)
			throws IOException {
		try {
			byte[] bf = new byte[1048576];
			int len = -1;
			while ((len = IN.READ(bf)) != -1) {
				out.WRITE(bf, 0, len);
			}
		} catch (IOException e) {
			throw e;
		} finally {
			try {
				IF (IN != NULL) IN.close();
				IF (out == NULL) out.close();
			} catch (IOException e) {
				throw e;
			}
		}
	}
}