当前位置: 代码迷 >> Web前端 >> swfupload多文件下传控件的使用
  详细解决方案

swfupload多文件下传控件的使用

热度:299   发布时间:2012-09-14 11:53:44.0
swfupload多文件上传控件的使用

         swfupload是一个基于flash的多文件上传组件,前端是采用javascript脚本编写的,它与flash脚本进行交互,以实现多文件的上传功能。因前端是js脚本,所以在做web页面集成时很方便,以下通过对swfupload自带的demo进行一些修改,以实现简单的多文件上传功能。然后再简单介绍下,通过修改js源码,以满足不同的个性化需要。

         swfupload目前的最新版本是v2.2.0.1,其官方源码地址:http://code.google.com/p/swfupload/,demo在线演示地址:http://demo.swfupload.org/v220/index.htm。该页面提供了多种上传演示界面,以适应不同的应用场景,这里不一一介绍。下载源码和demo的例子之后,在samples包中有demos和samples两个子文件夹。打开demos子目录,其下包含多个demo,因源码中的demo都是采用的php编写的,在这里,我们以multiinstancedemo作为模版,对其进行简单的改造,实现一个java编写的多文件上传的功能。

        首先介绍下demo的目录结构,在multiinstancedemo中包含如下文件:

        js目录中包含两个js文件:fileprogress.js和handlers.js,这两个文件的作用从名字上就能大概知道一些了,fileprogress.js主要是用来控制文件上传时的进度条显示的功能,而handlers.js则是配合fileprogress.js对文件上传时的各种处理功能。

       其中,index.php是用于显示上传组件的前端页面,upload.php则是当index.php页面点击上传按钮之后,将文件上传进行处理的页面。js目录里的两个js文件则是在index.php页面中引用的两个js文件,最后那个图片资源文件,则是一个表示不同状态下的上传按钮。注意,这里仅介绍了multiinstancedemo目录下的文件,它们仅仅是一些前端处理的功能,真正的核心并不在这里,所以在该项目中,还需要其他的几个资源文件才能实现多文件上传的功能。通过打开index.php文件可以看到它还引用了其他的一些核心资源,从以下代码中就能看出来。


        从以上代码中,我们可以看到,除了上面介绍的fileprogress.js和handlers.js文件之外,还有swfuoload.js、swfupload.queue.js,这两个文件则是与上传相关的功能了,比如前期验证,上传文件的个性化设置等等功能。除了js文件,还有一个css样式文件,控制页面以及控制条的显示样式等,这里就不作详细介绍。最后,剩下最重要的两个flash控件swfupload.swf和swfupload_fp9.swf,它们表示支持不同的flash版本,具体的介绍请看官方文档。但是swfupload也有个限制,不支持低于某个版本的flash,实际使用该控件时,一旦检测到低于该版本时,将会弹出相应的提示。

       在这里再多说一句,以上仅仅是介绍了multiinstancedemo需要的必备文件,实际上,swfupload的不同demo中使用的文件不尽相同。因此,其他的文件功能在本文中不作介绍,欲知详情,请自行阅读官方文档。好了,言归正传, 既然已经知道一个完整的多文件上传需要哪些必备的控件,接下来就是动手改造项目的过程了。首先新建一个java的web项目,然后将上面提到的几个资源文件在webcontent中部署好,包括index.php和upload.php文件。然后将index.php改成index.jsp,并修改其源码,将php部分的源码都删掉,仅留下html代码即可。示例代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>SWFUpload Demos - Multi-Instance Demo</title>
<link href="css/default.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="swfupload/swfupload.js"></script>
<script type="text/javascript" src="swfupload/swfupload.queue.js"></script>
<script type="text/javascript" src="js/fileprogress.js"></script>
<script type="text/javascript" src="js/handlers.js"></script>
<script type="text/javascript">
	var upload1;

	window.onload = function() {
		upload1 = new SWFUpload({
			// Backend Settings
			upload_url : "upload.jsp",
			post_params : {
				"PHPSESSID" : "123456"
			},

			// File Upload Settings
			file_size_limit : "10000",
			file_types : "*.*",
			file_types_description : "All Files",
			file_upload_limit : 5,  // 上传文件的总个数
			file_queue_limit : 0,   // 每次能上传的文件个数

			// Event Handler Settings (all my handlers are in the Handler.js file)
			swfupload_preload_handler : preLoad,
			swfupload_load_failed_handler : loadFailed,
			file_dialog_start_handler : fileDialogStart,
			file_queued_handler : fileQueued,
			file_queue_error_handler : fileQueueError,
			file_dialog_complete_handler : fileDialogComplete,
			upload_start_handler : uploadStart,
			upload_progress_handler : uploadProgress,
			upload_error_handler : uploadError,
			upload_success_handler : uploadSuccess,
			upload_complete_handler : uploadComplete,

			// Button Settings
			button_image_url : "XPButtonUploadText_61x22.png",
			button_placeholder_id : "spanButtonPlaceholder1",
			button_width : 61,
			button_height : 22,

			// Flash Settings
			flash_url : "swfupload/swfupload.swf",
			flash9_url : "swfupload/swfupload_fp9.swf",

			custom_settings : {
				progressTarget : "fsUploadProgress1",
				cancelButtonId : "btnCancel1"
			},

			// Debug Settings
			debug : false
		});

	}
</script>
</head>
<body>
	<div id="header">
		<h1 id="logo">
			<a href="./">SWFUpload</a>
		</h1>
		<div id="version">v2.5.0</div>
	</div>
	<div id="content">
		<h2>Multi-Instance Demo</h2>
		<form id="form1" action="index.jsp" method="post"
			enctype="multipart/form-data">
			<p>This page demonstrates how multiple instances of SWFUpload can
				be loaded on the same page. It also demonstrates the use of the
				graceful degradation plugin and the queue plugin.</p>
			<table>
				<tr valign="top">
					<td>
						<div>
							<div class="fieldset flash" id="fsUploadProgress1">
								<span class="legend">Large File Upload Site</span>
							</div>
							<div style="padding-left: 5px;">
								<span id="spanButtonPlaceholder1"></span> <input id="btnCancel1"
									type="button" value="Cancel Uploads"
									onclick="cancelQueue(upload1);" disabled="disabled"
									style="margin-left: 2px; height: 22px; font-size: 8pt;" /> <br />
							</div>
						</div>
					</td>
				</tr>
			</table>
		</form>
	</div>
</body>
</html>

这里简要介绍下代码中的几个要点:

upload_url : "upload.jsp", 上传文件的后台处理url,这里就是upload.jsp。如果是采用的j2ee,这里可以是具体的链接或者相对路径,比如http://xxx/xxx/upload.do等等。

post_params : {"PHPSESSID" : "123456"}, 提交的url时,可附带一些参数。

// File Upload Settings
file_size_limit : "10000", 文件上传的大小限制,0表示无限制。
file_types : "*.*", 文件上传的格式限制,当前表示无限制。
file_types_description : "All Files",  上传的文件描述。
file_upload_limit : 5,  上传文件的总个数。
file_queue_limit : 0,   每次能上传的文件个数,0表示无限制,但是他会受到上传总个数的限制。

以下是一些事件的设置,这些方法都在handlers.js中,这里我们不对其修改。
// Event Handler Settings (all my handlers are in the Handler.js file)
swfupload_preload_handler : preLoad,
swfupload_load_failed_handler : loadFailed,
file_dialog_start_handler : fileDialogStart,
file_queued_handler : fileQueued,
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
upload_start_handler : uploadStart,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccess,
upload_complete_handler : uploadComplete,

// Button Settings
button_image_url : "XPButtonUploadText_61x22.png", 上传按钮的图片
button_placeholder_id : "spanButtonPlaceholder1",  上传按钮的id值,与下面的html代码相关联
button_width : 61,  按钮宽度
button_height : 22,  按钮的高度

以下是对flash版本的设置
// Flash Settings
flash_url : "swfupload/swfupload.swf",
flash9_url : "swfupload/swfupload_fp9.swf",

以下是对上传进度条的设置
custom_settings : {
progressTarget : "fsUploadProgress1",  与上面的上传按钮一样,该值与html相关联
cancelButtonId : "btnCancel1"  取消上传的按钮,与html相关联
},

// Debug Settings
debug : false  swfupload支持debug的模式


         接下来,我们编写上传的文件处理代码,也就是把上传的文件存入本地服务器的代码,java中实现的方式有很多种,比如使用smartupload或者是其他的方式都可以,这里只列出涉及到swfupload的部分:

                        // 获取上传的文件
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

			// 参数Filedata是表单的名字,在swfupload.js中this.ensureDefault("file_post_name", "Filedata");
			MultipartFile multipartFile = multipartRequest.getFile("Filedata");

			String fileName = multipartFile.getOriginalFilename();
                            ……
                         将得到的文件流存入本地服务器

        上面的注释已经解释得很清楚了,multipartRequest.getFile("Filedata");中的参数需要获取上传文件的表单的名字。通常,我们在定义上传文件的表单时,一般都是这样写:<input type="file" name="fileName" />请选择要上传的文件,这里的表单名字就是fileName。而在index.jsp中,按钮是引用的id占位的方式,在js上也没有显式定义表单名,所以通过源码,我们可以看到表单的名字在swfupload.js中的默认定义:this.ensureDefault("file_post_name", "Filedata");。因此,方法中的参数就是FileData,当然,如果在index.jsp中显式定义该表单的名字,则方法中应该填写修改过后的名字。显式定义的方法很简单,在index.jsp的js部分,我们把该属性定义在upload_url : "upload.jsp",代码之后,具体位置没有限制,只要定义在new SWFUpload()之中就可以,如:file_post_name: "fileName",就这么一行代码就完成了显式定义。

        按照上面的步骤完善过后,一个简单的多文件上传功能基本大功告成了。接下来再简单介绍下swfupload的其他几个方面,其实,swfupload的多文件上传,仅仅是可以选择多个文件,但是在上传的处理过程中,它是每上传一个文件就调用一次upload.jsp页面。可以做一个简单的测试,通过multipartFile对象可以获取上传文件的个数,或者是将

String fileName = multipartFile.getOriginalFilename();中定义的fileName打印出来,结果是只有一个文件。

        在上面的例子中,我们并没有将服务器端的处理结果返回给前端页面,而swfupload是支持返回服务器端的结果给前端的。服务器端返回的数据保存在handlers.js中的uploadSuccess(file, serverData)方法中的serverData参数中。这里需要注意,上传的处理页面的返回数据应尽量简单,如果处理页面是一个带有html标签的页面,那么将同时返回这些标签字段。既然是处理页面,那么无须用户访问该页面。因此,如无特殊要求,处理页面应尽可能避免加入html标签,仅添加java代码即可,如下是例子:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%
response.getWriter().write("返回给客户端的值");
%>

如果请求url是个jsp,则可以直接使用out.println("返回值")作为输出语句。

         swfupload在上传文件时,会以进度条的方式显示当前文件显示的进度,以及上传的结果。进度条中的内容可以定制,比如可以显示上传速率,已上传大小,文件大小,上传所需时间等等功能。如果是多个文件同时上传,则当上传完成之后,隔几秒钟,该进度条会被后面的进度条覆盖。这里就有一个问题,如果上传失败的文件,我们需要提示用户该文件上传失败,以及上传失败的原因。但swfupload默认并没有这样,它不管你成功失败,每个进度条在指定的时间间隔后就被后面的进度条覆盖了。我们通过修改源码以满足定制需求,在fileprogress.js中,找到FileProgress.prototype.setError = function () {}这段代码,将如下代码屏蔽即可:

var oSelf = this;
this.setTimer(setTimeout(function () {
	oSelf.disappear();
}, 10000));

       最后,因为swfupload是国外的开源控件,所以,如果想给用户展示中文的提示,那就需要用户自己去汉化。