Uploadify + Struts2 应用之分析与详解

fmms 12年前

Uploadify是一个Jquery框架下处理批量文件上传的插件,支持多种服务器端软件。遗憾的是,官网(www.uploadify.com)的说明文档做得很不完善,着重于说明Js部分的配置,而没有对服务端的数据接口进行详细说明。而且由于与服务器端进行数据交互的部分被封装在swf文件中,也很难从源代码进行分析。

 

1) 分析

基于此,为了探索Uploadify在Struts2下的应用接口数据,编写了个小工具程序RequestObserver如下:

 

package utils;    import java.util.Enumeration;  import java.util.Iterator;  import java.util.Map;    import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpSession;    import com.opensymphony.xwork2.ognl.OgnlValueStack;      public class RequestObserver {      private HttpServletRequest request;           public RequestObserver(HttpServletRequest request) {          this.request = request;      }           public void observe() {          String name,pvalue;          Object avalue;          Enumeration enum1;            System.out.println("/***************** Request Observer (Author: Alex Nie)**************/");                   // observe Request Header          enum1 = request.getHeaderNames();          System.out.println("Request Header:");          while (enum1.hasMoreElements()) {              name = (String)enum1.nextElement();              pvalue = request.getHeader(name);              System.out.println("  " + name + " ---- " + pvalue);          }          enum1 = request.getParameterNames();            // observe Request Parameters          System.out.println("Request Parameters:");          while (enum1.hasMoreElements()) {              name = (String)enum1.nextElement();              pvalue = request.getParameter(name);              System.out.println("  " + name + " ---- " + pvalue);          }          enum1 = request.getAttributeNames();            // observe Request Attributes          System.out.println("Request Attributes:");          while (enum1.hasMoreElements()) {              name = (String)enum1.nextElement();              avalue = request.getAttribute(name);              System.out.println("  " + name + " ---- " + avalue);                           // observe OgnlValueStack bind by Struts 2              if (avalue instanceof OgnlValueStack) {                  avalue = (OgnlValueStack)avalue;                  Map<String,Object> m = ((OgnlValueStack) avalue).getContext();                  System.out.println("  >> OgnlValueStack:");                  Iterator it = m.keySet().iterator();                  Object key;                  while (it.hasNext()) {                      key = it.next();                      System.out.println ("        " + key + " ---- " + m.get(key));                  }              }          }            // observe Request Session          HttpSession session = request.getSession(false);          System.out.println("session: " + session);          if (session!=null)          {              System.out.println("  sessionId: " + session.getId());              enum1 = session.getAttributeNames();              System.out.println("Session Attributes:");              while (enum1.hasMoreElements()) {                  name = (String)enum1.nextElement();                  avalue = session.getAttribute(name);                  System.out.println("  " + name + " ---- " + avalue);              }          }          System.out.println("/***************** End of Request Observer (Author: Alex Nie)**************/");               }       }

 

在按照官网的说明进行简单配置后,从浏览器触发上传文件操作,在服务器端的Action中接收到相应的Request后,利用上述工具程序输出分析Request中的数据,发现如下:

 

分析结果

在进行批量文件上传时,Uploadify为每一个上传文件发起一次服务器连接。

 

在每一次连接中,Uploadify向服务器端传递了7个参数,其中通过request parameters传递了4个String类型参数

Filename: 待上传的文件原名, 内容与后述的xxxxFileName相同

fileext: 允许上传的文件类型,由客户段Js代码中指定的fileExt参数指定

folder: 上传文件在服务期上的保存路径,由客户段Js代码中指定的folder参数指定

Upload:  暂无用处

 

通过request attributes 传递了3个参数

xxxx : 文件类型,上传的文件内容,xxxx由客户段Js代码中指定的fileDataName参数指定

xxxxFileName: 字符串类型,上传的文件的原名,xxxx由客户段Js代码中指定的fileDataName参数指定,内容与前述的Filename相同
uploadifyContentType: 暂无用处

 

以上7个参数在服务器端都被Struts2封装,在Action都可直接使用。要注意的是参数名称的大小写和Js端的大小写并不完全相同,有的在 Js中小写服务器端大写,有的刚好相反。此外有两个参数内容相同,这些大约是Uploadify未来在代码风格与约定方面可以改进的地方。

 

清楚了数据接口,Struts2下对应Uploadify的Action该怎么写就很清楚了,接下来以批量上传照片为例进行说明。

 

 

2) 应用详解


html

<input id="file_upload" name="photo" type="file"/>    <div id="fileQueue"></div>

 

 

Javascript

引入jquery-1.4.2.min.js, swfobject.js, jquery.uploadify.v2.1.4.min.js

引入自己的上传用Js代码如下(精简说明版):

      $(document).ready(function() {          $('#file_upload').uploadify({                // 页面相关              'uploader'       : '/js/uploadify/uploadify.swf', //组件自带的flash,路径根据情况自行调整              'cancelImg'      : '/js/uploadify/cancel.png',//取消上传文件的按钮图片                'queueID'        : 'fileQueue', //放置上传文件及上传进度的Html元素Id                'queueSizeLimit' : 10, //一次最多选择多少个文件上传                     // 控制开关                'auto'           : false, //是否选取文件后自动上传,建议关闭              'multi'          : true, //多文件上传必须打开                     // 服务器脚本                'script'         : 'uploadify.action', //Struts2下处理上传的action路径              'scriptData'     : {'userid': '12345', 'username': 'Alex Nie'}, //自身业务需要向服务器端传递的数据                     // 传递给服务器参数                'folder'         : '/upload', //上传文件的目录,将作为'folder'参数传递给服务器              'fileDataName'   : 'photo', //它决定了最重要的两个上传参数名称,本例中将为文件'photo'和文件名'photoFileName'                'fileExt'        : '*.gid;*.jpg;*.jpeg', //允许的文件类型,在客户端约束用户的文件选择,并将作为'fileext'参数传递给服务器供校验用                     // 其它                'fileDesc'       : '*.gif;*.jpg;*.jpeg', //显示在本地选择文件对话框的文件类型下拉框中              'sizeLimit'      : 100*1024 // 单个文件的最大尺寸(字节为单位)          });        });                 function uploadFile(){//上传文件           jQuery('#file_upload').uploadifyUpload();          }

 

 

Java

在此不列出具体代码了,只说明一下服务器端UploadifyAction程序的大致流程:

定义以下变量,且生成它们的get和set方法

    private File photo;
    private String photoFileName,fileext,folder;

1) 分析'fileext',分解出允许的所有文件类型;

2) 校验photoFileName是否在允许的文件类型中

3) 校验文件photo的大小是否超标(遗憾的是,Uploadify不会把Js中定义的'sizeLimit'传递给服务器,服务器端必须自行定义)

4) 校验folder指定的路径是否合法

5) 在folder指定的路径下保存文件photo,根据业务需要可能要为它取名而不是用原文件名photoFileName

6) 向response写入成功或失败返回信息,供页面使用

注:如果信任浏览器端的文件类型和文件尺寸约束校验,也可以省略第2、第3步和第4步,不过为了防止恶意的客户端伪装,最好不要省略它们。

 

 

其它几个值得使用的Uploadify选项

            'removeCompleted': false //完成上传后是否自动清除网页上的文件列表

            'displayData'    : 'percentage',//有speed和percentage两种选择,一个显示速度,一个显示完成百分比

            'buttonImg'      : '/images/mybutton.jpg', 可用图片替换掉页面上传按钮的英文文字显示,避开直接替换成中文文字会遇到的编码问题。

 

 

解决Uploadify缺省的英文提示窗问题

编辑jquery.uploadify.v2.1.4.min.js,查找'alert'和'confirm'调用,把提示信息从英文改成中文。

 

转自:http://blog.csdn.net/alexandertech/article/details/6428366