笔者在网上查找流行的上传组件,swfupload引入眼帘,受到JavaEye的一篇文章启发,历时三天,加以研究,现将心得奉上,献礼JavaEye。

由于笔者才疏学浅,经验匮乏,介绍不深入,仅供菜鸟参考,还望高手赐教。

一、准备工作

从官网上http://www.swfupload.org/下载发布版v2.2.0.1,仅取下载文件中的SWFUpload.js和swfupload.swf即可,另外可利用官网上的DEMO,从中获取一张PNG图片。

swfupload.swf是上传组件的核心,一个特制的FLASH,具有浏览文件,上传文件的功能,以按钮形式体现在用户眼前,上文中提及的PNG图片浮在按钮上,可增强视觉效果。SWFUpload.js与swfupload.swf交互,向开发者提供操作接口。

二、使用步骤

文档中指出,SWFUpload并不是拖放式的上传控件,它需要使用者具备JavaScript(以下简称JS)和DOM的知识,进行UI界面的设计。

  笔者借助J2EE平台实例,步步为营,介绍其使用方法。

  1.部署组件

  将swfupload.swf、SWFUpload.js和upload.png图片(上文提及的图片)正确放置于WEB项目中,并且新建upload.jsp文件与前三者置于同一目录中。下图中tryswfupload为WEB项目名称。  

在upload.jsp中引入swfupload.js组件:

<script type="text/javascript" src="swfupload.js"></script>

  2.实例化swfupload组件

实例化swfupload组件的任务就是正确配置参数,方法是编写JS代码,目前急需配置两方面内容:一是指定swfupload.swf的物理位置;二是准确配置flash中的上传按钮。

button_placeholder_id属性的值spanButtonPlaceholder为上传按钮的ID值,因此可以显示在JSP中。读者须注意,按钮的高和宽一定要指定,否则flash无法显示。至此,JSP页面已经实现用户选择文件的功能。

读者不妨试试,便会看到运行效果图。

点击“选择文件”按钮,文件对话框即刻跳出,用户选择多个文件后,对话框立即关闭,选择的文件进入排队序列,等待上传。当调用SWFUpload 对象的startUpload方法执行上传命令。在此例中,swfu已经实例化为SWFUpload 对象,故可以在JSP中添加一个按钮,在其点击事件中调其该方法。在JSP中添加代码:

<button onclick="swfu.startUpload()">上传</button>

虽如此,但文件没有上传到服务器上,至少客户端不知道上传的目的地。

  3.指定客户端将上传信息发送至服务器的URL——struts2登场

swfupload将upload_url属性值作为客户端将文件上传请求信息发送至服务器的URL,读者可理解为struts2表单中的action属性值,upload_url属性值默认为web项目的主页。笔者仅介绍struts2如何接收请求。

struts2已经实现了上传功能,笔者不作详细介绍(由于struts2实现了无缝整合,开发者仅需要将上传的临时进行复制即可,其使用方法易于掌握)。

使用struts2的上传功能,开发者需要知道file标签的name属性值,在此基础上,编写action类即可,并在struts.xml文件中配置名字其名字。在swfupload中,file标签的name属性等价为file_post_name属性,其默认值为Filedata。至此,具备了URL和name属性值,便可开始struts2整合之旅。

首先将action的名字赋值给 swfupload中upload_url属性。接着编写自己的action类,类中包含两个属性Filedata和Filename,Filedata和file_post_name值相同(文档推荐使用默认值Filedata)。 Filedata指向了struts2上传的临时文件路径(action中的execute函数执行完毕,临时文件将被删除),Filename为上传文件的名字。Execute函数实现将临时文件复制到指定的目录(此例将它放在WEB项目下bin目录下的upload中)。此例action的名字为“upload”,在JSP中将upload_url属性赋值为upload。

  4.添加捕获事件函数

swfupload仅实现了后台操作,前台的处理空间留给了开发者,它采用事件触发机制,让开发者捕获特定事件,并鼓励开发者自定义对应的事件处理函数(笔者定义为:捕获事件函数)进行相应处理。即当swfupload内部某一特定事件发生,便触发JS函数,JS函数通过回调机制将函数参数继续传入自定义的JS函数中。Swfupload通过固定的事件函数名属性值寻找自定义的JS函数,所以在初始化工作中,将自定义的JS函数名赋值给swfupload指定的对应属性即可。

比如,当你选择上传文件后,文件对话框随即关闭,产生关闭对话框完成的事件,内置的fileDialogComplete函数被触发,函数执行完必要的操作后,将整个参数信息传入file_dialog_complete_handler属性值对应的JS函数。所以,开发者仅需将自定义的JS函数名赋值给file_dialog_complete_handler属性即可。Swfupload向外提供的所有事件以及对应的函数定义,文档有详细说明。笔者将“添加捕获XXX事件函数”定义为:自定义JS函数用来捕捉XXX事件,XXX表示swfupload内部捕获事件函数,并函数名赋值给XXX事件对应的属性。比如“添加捕获fileDialogComplete事件函数”表示先自定义JS函数(假设函数名为fileDialogCompleteHandler),用来捕获fileDialogComplete事件,并且将fileDialogCompleteHandler赋值给fileDialogComplete事件对应的属性file_dialog_complete_handler。

为便于管理,笔者建议新建一个JS文件,专门用来存放捕获事件函数,此例为handler.js,注意在JSP中要将其引入。

<script type="text/javascript" src="handler.js"></script>

  5.实现批量上传

swfupload不自动批量上传,读者可以尝试选择两个文件点击上传按钮,在服务器端却仅有一个文件,当再次点击上传按钮后,服务器端又多出一个文件。Swfupload虽支持批量上传,但本质仍是单个文件依次上传,这有别于传统设计模式,但其益处却避免了开发者编写大量代码,迭代分析所选文件。

文档指出,添加捕获uploadComplete事件函数(其对应属性为upload_complete_handler),并在其中调用上传函数startUpload,通过递归的方式实现批量上传,即在某个文件上传完成后,再次启动文件上传。此例,该函数被定义为uploadComplete。

在JSP中添加upload_complete_handler属性并赋值为uploadComplete。

  6.显示上传文件列表

显示出上传文件列表能够增强用户体验,因为用户将看见选择的文件信息。下文介绍将选择的文件以表格形式显示出来,每行内容为依次为文件名、大小、状态(QUEUED、ERROR、COMPLETE)。

读者不妨在文档中仔细查找是否存在其参数包含file类型集合的API函数,其结果必然徒劳,因为只有参数为file类型的API函数。这在上文已有介绍:swfupload本质依靠单个文件形式上传。该知识点对于对于灵活掌握swfupload举足轻重。故当选择某一文件后,在表格追加显示该文件信息,在文件对话框关闭后,显示表格(表格初始状态为隐藏,在JSP中定义)。

fileDialogComplete事件在选择上传文件后产生,其对应的事件属性为file_dialog_complete_handler,对应的内置函数为fileDialogComplete(number of files selected, number of files queued, total number of files in the queued),虽然三个整型参数无法提供所选文件具体信息,但可实现让隐藏的表格显示出来。添加捕获fileDialogComplete事件函数。

在JSP中添加file_dialog_complete_handler属性并赋值为fileDialogComplete。

在fileDialogComplete事件产生前, fileQueued事件已经发生。fileQueued事件表示所选文件进入上传排队序列,对应的事件属性为file_queued_handler,对应的内置函数为fileQueued(file object),它的发生频率取决于所选文件的个数。通过添加捕获fileQueued事件函数,可实现文件列表动态显示。

fileQueued函数配合状态转换函数showStatus动态添加表格行,其中在showStatus函数中,SWFUpload是全局对象,它包含一些只读对象,文档中有说明,此例仅使用FILE_STATUS常量。

在JSP中添加file_queued_handler属性并赋值为fileQueued。

表格行能动态生成,但其中的状态字段仍然保持最初状态QUEUED,无法动态体现文件上传后的实际状态(ERROR、COMPLETE)。笔者的方法是通过row.id = file.id将文件和表格的行绑定,根据文件定位其所属表格行,由此改变状态单元格数据。

上传错误将发生uploadError事件,属性为upload_error_handler,内置函数为uploadError(file object, error code, message);上传成功将发生uploadSuccess事件,属性为 upload_success_handler,内置函数为uploadSuccess(file object, server data, received response)。分别添加这两个捕获事件函数,在函数内文件取出状态,动态改变状态字段值。

在JSP中添加upload_error_handler属性并赋值为uploadError,添加upload_success_handler属性并赋值为uploadSuccess。

  至此,JSP中SWFUpload的实例化代码为:

三、从页面跳转到请求流程

此时,本应划上句号,因为所选文件已经上传到upload目录下,但笔者还是想就部分朋友反映“上传完成后,页面不跳转”现象谈谈个人观点。页面不跳转是一个不争的事实,你大可反复尝试。难道这意味着struts2页面跳转功能失效呢?笔者在没搞清楚swfupload原理前,也为之困扰。struts2页面跳转功能仍然良好地在运转,不过它将跳转的页面回响至swfupload,swfupload用内置函数uploadSuccess捕获。对此,理解用户从访问上传页面到页面跳转的整个请求过程至关重要。

首先浏览器访问WEB服务器,打开上传页面,这个过程和打开网页原理相同。当点击“选择文件”按钮后,浏览器通过JS启用swfupload后退出舞台,flash登场。当点击“上传”按钮,flash模拟浏览器向WEB服务器发起连接(新开session),向WEB服务器发送上传信息。可见,当WEB服务器返回信息,目的地不是浏览器,而是flash。整个过程,flash始终和JS紧密交融,将发生的事件通知JS,给开发者留下了足够的编程空间。这不得不赞叹swfupload,将flash设计得淋漓尽致,将JS、WEB服务器、浏览器天衣无缝融入一体。

当WEB服务器响应代码为200时(swfupload表示上传成功的默认代码,可通过修改http_success属性值改变),swfupload便产生上传成功事件,故可通过添加捕获上传成功事件函数得到struts2返回的页面,但不可通过uploadError事件处理struts2拦截器抛出的异常信息,因为swfupload无法解析WEB服务器返回的信息,它仅靠WEB服务器返回代码产生相应事件。

上传成功事件对应的内置函数为uploadSuccess(file object, server data, received response),其中第一个参数为上传的文件,第二个参数为服务器返回的数据,第三个参数为布尔值,从字面上看,估计表示是否收到信息。struts2跳转的页面以HTML代码形式赋值给第二个参数,故可在该捕获事件函数中,置入document.write(server_data)语句,实现页面跳转。

笔者认为swfupload并不希望开发者这样做,因为单个文件的上传机制将导致出现上传完一个文件页面就跳转一次的荒唐现象。其实,只要任何时候调用document.write方法,swfupload立即失效,切忌这样做。

对于实现批量上传成功页面跳转的方法,笔者建议可将server_data缓存,在捕获uploadSuccess事件函数中,如果上传队列为空(getStats().files_queued > 0),再用document.write向swfupload say Goodbye。


转贴:http://blog.csdn.net/lfp0202/article/details/5800745

浅谈如何使用swfupload工具与struts2无缝相接的更多相关文章

  1. 浅谈maven自动化构建工具

    转载https://blog.csdn.net/zxm1306192988/article/details/76209062 Maven是什么[what] 1.Maven 是 Apache 软件基金会 ...

  2. 浅谈ABB机器人(工具坐标,工件坐标,有效载荷)

    工具坐标(tool): 使tcl坐标偏移到工具上,例如焊接工作,使机器人工作点切入焊枪点上 mass:工具的重量 xyz:偏移距离的大小 验证:通过手动模式,切换至自定义工具,重定向 工件坐标(wob ...

  3. 浅谈Webpack模块打包工具一

    为什么要使用模块打包工具 1.模块化开发ES Modules存在兼容性问题 打包之后成产阶段编译为ES5 解决兼容性问题 2.模块文件过多 网络请求频繁  开发阶段把散的模块打包成一个模块 解决网络请 ...

  4. 浅谈Webpack模块打包工具三

    Source Map 生产代码与开发代码完全不同,如果需要调试应用的话会非常的麻烦,错误信息无法定位,Soutce Map就会逆向得到源代码, 须在打包之后的代码文件的末尾位置例如添加//# sour ...

  5. 浅谈Webpack模块打包工具四

    Webpack 生产环境优化 生产环境和开发环境有很大的差异,生产环境只注重运行效率,开发环境主要开发效率,webpack4.0开始提出了(mode)模式的概念 针对不同的环境进行不同的配置,为不同的 ...

  6. 【转】浅谈自动特征构造工具Featuretools

    转自https://www.cnblogs.com/dogecheng/p/12659605.html 简介 特征工程在机器学习中具有重要意义,但是通过手动创造特征是一个缓慢且艰巨的过程.Python ...

  7. 浅谈自动特征构造工具Featuretools

    简介 特征工程在机器学习中具有重要意义,但是通过手动创造特征是一个缓慢且艰巨的过程.Python的特征工程库featuretools可以帮助我们简化这一过程.Featuretools是执行自动化特征工 ...

  8. 开发工具--浅谈Git

    工具|浅谈Git Git这个工具,是我一直想写文章,终于我实现了我的想法.在我开始写之前,发表一下自己的看法,git只是一个工具,既然已经认定是一个工具,那么一定具备工具这类的共同特征,请用面向对象的 ...

  9. 【转载】浅谈游戏开发之2D手游工具

    浅谈游戏开发之2D手游工具 来源:http://www.gameres.com/459713.html 游戏程序 平台类型: iOS Android  程序设计: 其它  编程语言:   引擎/SDK ...

随机推荐

  1. zoj3961(区间问题)

    点击打开zoj1961Let's Chat Time Limit: 1 Second      Memory Limit:65536 KB ACM (ACMers' Chatting Messenge ...

  2. WinForm 读写配置文件

    //读配置文件 方法(1) //ConfigurationManager.RefreshSection("appSettings"); //强制重新载入 string settin ...

  3. gitlab实时备份方案(非官方命令)

    gitlab自带的备份功能做不到实时备份,为了尽可能减少意外情况导致的丢失数据,自己搞了一个实时备份的功能. 备份的大头主要是两部分,数据库和代码库.数据库由DBA配置主备. 仓库经过测试,通过lsy ...

  4. 学习Ajax

    1.XHR对象 IE7+.Firefox.Opera.Chrome和Safari都支持原生XMLHttpRequest对象,IE6不支持,只支持ActiveXObject对象,该对象在IE11中已经不 ...

  5. Unity编辑器下重启

    我们项目AssetBundle打包走的是全自动化流程,打包之前要进行各种资源检测,如果检测顺利通过,则进入打包,否则提示错误资源名称及路径,打包中断!有时候即使资源检测通过也会打包崩溃,初步断定是Un ...

  6. python - 常用模块栗子

    前言  内容摘自Python参考手册(第4版) 及 自己测试后得出.仅作为一个简单记录,方便使用查询之用. 另 dir(func)及func.__doc__可以查看对象属性及说明文档. 序列Seque ...

  7. Spring读书笔记——bean创建(上)

    通过<Spring读书笔记--bean加载>和<Spring读书笔记--bean解析>,我们明白了两件事. Spring如何加载消化一个xml配置文件 Spring如何将xml ...

  8. popup方法

    popup方法: 一.创建一个页面 1.创建url和视图函数:: from django.shortcuts import render def p1(request): return render( ...

  9. 正确理解Mysql的列索引和多列索引

    MySQL数据库提供两种类型的索引,如果没正确设置,索引的利用效率会大打折扣却完全不知问题出在这. CREATE TABLE test ( id         INT NOT NULL, last_ ...

  10. JQuery-基础学习1

    1)JQuery语法 jquery语法是为HTML元素的选取编制,可以对元素执行某些操作. 基础语法是:$(selector).action() 美元符号定义JQuery 选择符(selector)& ...