<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ursob &#187; 文件上传</title>
	<atom:link href="http://ursob.org/tag/%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0/feed/" rel="self" type="application/rss+xml" />
	<link>http://ursob.org</link>
	<description>Code &#38;&#38; Riff</description>
	<lastBuildDate>Thu, 29 Jul 2010 09:37:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Struts批量上传文件</title>
		<link>http://ursob.org/2009/09/22/struts-batchupload/</link>
		<comments>http://ursob.org/2009/09/22/struts-batchupload/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 08:36:13 +0000</pubDate>
		<dc:creator>ripflowers</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Others]]></category>
		<category><![CDATA[Struts]]></category>
		<category><![CDATA[文件上传]]></category>

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

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:Courier New, Courier;">&lt;!--jsp上的form，这里一定要设置“enctype”--&gt;
&lt;html:form action=&quot;upload.do?method=upload&quot;  
	method=&quot;post&quot; enctype=&quot;multipart/form-data&gt;</pre></div></div>

<p>关于前台的实现就不再废话了，整体实现的效果如下：<br />
<img src="http://ursob.org/wp-content/uploads/2009/09/upload-300x107.jpg" alt="upload" title="upload" width="300" height="107" class="alignnone size-medium wp-image-67" /><br />
第二步，跟前台选择的文件对应的应该要有一个ActionForm，ActionFrom中要放置一个存放FormFile的集合，这样才能够实现文件的批量上传。ActionForm内容如下：</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:Courier New, Courier;">public class BatchUploadForm extends ActionForm <span style="color: #66cc66;">&#123;</span>
	private FormFile file;
	<span style="color: #66cc66;">//</span> 多附件上传这里应该是一个集合，所以这里用了List
	private List<span style="color: #66cc66;">&lt;</span>FormFile<span style="color: #66cc66;">&gt;</span> myFiles;
	public BatchUploadForm<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		myFiles <span style="color: #66cc66;">=</span> new ArrayList<span style="color: #66cc66;">&lt;</span>FormFile<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">//</span> 为了能够在页面初始显示一个file
		myFiles<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">ADD</span><span style="color: #66cc66;">&#40;</span>file<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
	public List<span style="color: #66cc66;">&lt;</span>FormFile<span style="color: #66cc66;">&gt;</span> getMyFiles<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #993333; font-weight: bold;">RETURN</span> myFiles;
	<span style="color: #66cc66;">&#125;</span>
	public void setMyFiles<span style="color: #66cc66;">&#40;</span>List<span style="color: #66cc66;">&lt;</span>FormFile<span style="color: #66cc66;">&gt;</span> myFiles<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		this<span style="color: #66cc66;">.</span>myFiles <span style="color: #66cc66;">=</span> myFiles;
	<span style="color: #66cc66;">&#125;</span>
	public FormFile getFile<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #993333; font-weight: bold;">RETURN</span> file;
	<span style="color: #66cc66;">&#125;</span>
	public void setFile<span style="color: #66cc66;">&#40;</span>FormFile<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		this<span style="color: #66cc66;">.</span>file <span style="color: #66cc66;">=</span> file;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>第三步，设置struts的配置文件，我的配置文件内容如下：</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:Courier New, Courier;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #00bbdd;">&lt;!DOCTYPE struts-config SYSTEM &quot;../struts-config_1_2.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;struts-config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;form-beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	    <span style="color: #808080; font-style: italic;">&lt;!--这里配置的Form替换成你的package--&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;form-bean</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;batchUploadForm&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;BatchUploadForm&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/form-beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;action-mappings<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #808080; font-style: italic;">&lt;!--这里要替换成你的Aciton和你的Forward,</span>
<span style="color: #808080; font-style: italic;">		                      batchUploadForm一定要配置，</span>
<span style="color: #808080; font-style: italic;">		                      既第二步中的ActionForm--&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;action</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;/upload&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;ResourceAction&quot;</span>				 <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;batchUploadForm&quot;</span></span>
<span style="color: #009900;">			 <span style="color: #000066;">parameter</span>=<span style="color: #ff0000;">&quot;method&quot;</span> </span>
<span style="color: #009900;">			 <span style="color: #000066;">scope</span>=<span style="color: #ff0000;">&quot;request&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;forward</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;success&quot;</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/action<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/action-mappings<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/struts-config<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:Courier New, Courier;"><span style="color: #66cc66;">//</span> 文件上传
public ActionForward upload<span style="color: #66cc66;">&#40;</span>ActionMapping mapping<span style="color: #66cc66;">,</span> ActionForm form<span style="color: #66cc66;">,</span>
		HttpServletRequest request<span style="color: #66cc66;">,</span> HttpServletResponse response<span style="color: #66cc66;">&#41;</span>
		throws Exception <span style="color: #66cc66;">&#123;</span>
&nbsp;
	BatchUploadForm uploadForm <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>BatchUploadForm<span style="color: #66cc66;">&#41;</span> form;
	<span style="color: #66cc66;">//</span> 这里是你文件上传的目标地址
	String uploadPath <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;&quot;</span>;
	<span style="color: #808080; font-style: italic;">/*
	 * 从Form中得到所有文件类型的元素， 返回的是一个Hashtable
	 */</span>
	Hashtable files <span style="color: #66cc66;">=</span> uploadForm<span style="color: #66cc66;">.</span>getMultipartRequestHandler<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">.</span>getFileElements<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">//</span> 循环得到所有的FormFile
	<span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #66cc66;">&#40;</span>Map<span style="color: #66cc66;">.</span>Entry<span style="color: #66cc66;">&lt;</span>String<span style="color: #66cc66;">,</span> FormFile<span style="color: #66cc66;">&gt;</span> entry : 
		<span style="color: #66cc66;">&#40;</span>Set<span style="color: #66cc66;">&lt;</span>Map<span style="color: #66cc66;">.</span>Entry<span style="color: #66cc66;">&lt;</span>String<span style="color: #66cc66;">,</span> FormFile<span style="color: #66cc66;">&gt;&gt;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>files<span style="color: #66cc66;">.</span>entrySet<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		FormFile ff <span style="color: #66cc66;">=</span> entry<span style="color: #66cc66;">.</span>getValue<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #808080; font-style: italic;">/*
		 * 这里的Files是我的一个实体bean 用来存储文件的路径等信息
		 */</span>
		Files file <span style="color: #66cc66;">=</span> new Files<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		String fileName <span style="color: #66cc66;">=</span> ff<span style="color: #66cc66;">.</span>getFileName<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #66cc66;">&#40;</span>StringUtils<span style="color: #66cc66;">.</span>isBlank<span style="color: #66cc66;">&#40;</span>fileName<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			continue;
		<span style="color: #66cc66;">&#125;</span> else <span style="color: #66cc66;">&#123;</span>
			<span style="color: #808080; font-style: italic;">/*
			 * 为避免上传的文件重名， 这里给文件生成随机的名称
			 */</span>
			String objId <span style="color: #66cc66;">=</span> UUID<span style="color: #66cc66;">.</span>randomUUID<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">.</span>toString<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">//</span> 得到文件的扩展名
			String extendName <span style="color: #66cc66;">=</span> fileName<span style="color: #66cc66;">.</span>substring<span style="color: #66cc66;">&#40;</span>fileName
			<span style="color: #66cc66;">.</span>lastIndexOf<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;.&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
			uploadPath <span style="color: #66cc66;">+=</span> <span style="color: #ff0000;">&quot;/&quot;</span> <span style="color: #66cc66;">+</span> objId <span style="color: #66cc66;">+</span> <span style="color: #ff0000;">&quot;.&quot;</span> <span style="color: #66cc66;">+</span> extendName;
			BufferedOutputStream outStream <span style="color: #66cc66;">=</span> new BufferedOutputStream<span style="color: #66cc66;">&#40;</span>
			new FileOutputStream<span style="color: #66cc66;">&#40;</span>uploadPath<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
			BufferedInputStream inputStream <span style="color: #66cc66;">=</span> new BufferedInputStream<span style="color: #66cc66;">&#40;</span>ff
			<span style="color: #66cc66;">.</span>getInputStream<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #808080; font-style: italic;">/*
			 * 这里的FileUtil是一个将文件流写到硬盘 的一个工具类，内容见下
			 */</span>
			<span style="color: #66cc66;">//</span> 保存文件到服务器
			FileUtil<span style="color: #66cc66;">.</span>createFile<span style="color: #66cc66;">&#40;</span>inputStream<span style="color: #66cc66;">,</span> outStream<span style="color: #66cc66;">&#41;</span>;
			<span style="color: #808080; font-style: italic;">/**
			 * 关于文件的基本信息 这里已经全部可以获取了， 怎么样保存就看你了！
			 */</span>
		<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
	<span style="color: #993333; font-weight: bold;">RETURN</span> <span style="color: #993333; font-weight: bold;">NULL</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:Courier New, Courier;">public class FileUtil <span style="color: #66cc66;">&#123;</span>
	public static void createFile<span style="color: #66cc66;">&#40;</span>InputStream <span style="color: #993333; font-weight: bold;">IN</span><span style="color: #66cc66;">,</span> 
                                              OutputStream out<span style="color: #66cc66;">&#41;</span>
			throws IOException <span style="color: #66cc66;">&#123;</span>
		try <span style="color: #66cc66;">&#123;</span>
			byte<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span> bf <span style="color: #66cc66;">=</span> new byte<span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1048576</span><span style="color: #66cc66;">&#93;</span>;
			int len <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span>;
			while <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>len <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">IN</span><span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">READ</span><span style="color: #66cc66;">&#40;</span>bf<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> !<span style="color: #66cc66;">=</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				out<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">WRITE</span><span style="color: #66cc66;">&#40;</span>bf<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span> len<span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span>
		<span style="color: #66cc66;">&#125;</span> catch <span style="color: #66cc66;">&#40;</span>IOException e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
			throw e;
		<span style="color: #66cc66;">&#125;</span> finally <span style="color: #66cc66;">&#123;</span>
			try <span style="color: #66cc66;">&#123;</span>
				<span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">IN</span> !<span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">IN</span><span style="color: #66cc66;">.</span>close<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
				<span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #66cc66;">&#40;</span>out <span style="color: #66cc66;">==</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span> out<span style="color: #66cc66;">.</span>close<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
			<span style="color: #66cc66;">&#125;</span> catch <span style="color: #66cc66;">&#40;</span>IOException e<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
				throw e;
			<span style="color: #66cc66;">&#125;</span>
		<span style="color: #66cc66;">&#125;</span>
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://ursob.org/2009/09/22/struts-batchupload/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
