Chinaunix首页 | 论坛 | 博客
  • 博客访问: 587550
  • 博文数量: 805
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 5000
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 14:22
文章分类

全部博文(805)

文章存档

2011年(1)

2008年(804)

我的朋友

分类:

2008-10-17 14:27:09

动机:

        2006年底Google了一下AJAX Upload实现,结果没有发现很完整的Java实现。硕果仅存的就是TELIO公司的Pierre-Alexandre发表的《AJAX Upload progress monitor for Commons-FileUpload Example》文中提供的ajax-upload-1.0.war。

        虽然上文中完成Upload工作的是Apache的Common-FileUpload组件,但在其代码中所使用的FileUpload1.1版本并没有1.2版本所提供的上传处理Listener功能,这就对检测文件上传情况造成了困难。我想正是这个原因致使Pierre-Alexandre使用了DWR+MonitoredDiskFileItem、MonitoredDiskFileItemFactory类(分别继承DiskFileItem、DiskFileItemFactory)的方式:前者负责在web客户端进行Remote Call;后者在进行文件数据读取时统计数据总量、读取数据量、处理文件总数,并保存于Session中,以供web客户端通过DWR远程调用UploadMonitor类的getUploadInfo方法进行轮询(Poll)。

        从本人观点出发,Pierre-Alexandre实现的不足之处:
        1.没有用户取消上传功能;
        2.完全的DWR实现,没有使用Prototype,对于不会使用DWR的开发者来讲有一定的知识局限性,而且由于DWR的个性而造成不便将此实现集成到项目中。



Prototype+Servlet的实现:

image
Prototype+Servlet的Example


        所以出于研究Prototype之目的,本人经过仔细思考,尝试实现了一个Prototype+Servlet的简单Example。其工作流程很简单:
1.在Form提交上传文件Field的同时,使用AJAX周期性地从Servlet轮询上传状态信息;
2.然后,根据此信息更新进度条和相关文字,及时反映文件传输状态;
3.如果用户取消上传操作,则进行相应的现场清理工作:删除已经上传的文件,在Form提交页面中显示相关信息;
4.如果上传完毕,在Form提交页面中显示已经上传的文件内容(或链接),也可以与一些AJAX SlideShow应用结合在一起。

服务器端代码:

        Bean序列化/反序列化工作:XmlUnSerializer这个类虽然不能够通吃任何模样的Bean,但应付一般的Bean、具有Collection类型属性的Bean和Bean List来讲还是够用的。
        {XmlUnSerializer类的核心方法serializeBean和serializeBeanList}:

        /**
         * 将bean系列化为UTF-8编码的xml
         * @param beanObj
         * @return
         * @throws IOException
         */
        public static String serializeBean(Object beanObj) throws IOException{
        …
        }
        /**
         * 将bean列表序列化为UTF-8编码的xml
         * @param beanObj
         * @return
         * @throws IOException
         */
        public static String serializeBeanList(Object beanListObj) throws IOException{
        …
        }


        文件上传状态Bean:使用FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与web客户端之间通信的媒介物:通过对这个类对象进行XML序列化作为服务器回应发送给web客户端,web客户端使用JavaScript对其进行反序列化处理获得JavaScript版本的文件上传状态对象。
        {FileUploadStatus的属性}:

        //上传总量
        private long uploadTotalSize=0;
        //读取上传总量
        private long readTotalSize=0;
        //当前上传文件号
        private int currentUploadFileNum=0;
        //成功读取上传文件数
        private int successUploadFileCount=0;
        //状态
        private String status="";
        //处理起始时间
        private long processStartTime=0l;
        //处理终止时间
        private long processEndTime=0l;
        //处理执行时间
        private long processRunningTime=0l;
        //上传文件URL列表
        private List uploadFileUrlList=new ArrayList();
        //取消上传
        private boolean cancel=false;
        //上传base目录
        private String baseDir="";


        文件上传状态监视工作:使用Common-FileUpload 1.2版本(20070103)。此版本与1.1版的区别在于提供了能够监视文件上传情况的ProcessListener接口,使开发者通过FileUploadBase类对象的setProcessListener方法植入自己的Listener,而且实现这个Listener很简单。
        {FileUploadListener主要方法update}:

/**
* 更新状态
* @param pBytesRead 读取字节总数
* @param pContentLength 数据总长度
* @param pItems 当前正在被读取的field号
*/
public void update(long pBytesRead, long pContentLength, int pItems){
FileUploadStatus fuploadStatus=BackGroundService.takeOutFileUploadStatusBean(this.session);
logger.debug("当前正在处理第" + pItems+"个文件");
fuploadStatus.setUploadTotalSize(pContentLength);
    //读取完成
if (pContentLength == -1) {
   logger.debug("读取完成:读取了 " + pBytesRead + " bytes.");
   fuploadStatus.setStatus("完成对" + pItems+"个文件的读取:读取了 " + pBytesRead + " bytes.");
   fuploadStatus.setReadTotalSize(pBytesRead);
   fuploadStatus.setSuccessUploadFileCount(pItems);
   fuploadStatus.setProcessEndTime(System.currentTimeMillis());
   fuploadStatus.setProcessRunningTime(fuploadStatus.getProcessEndTime());
            //读取中
    } else {
     logger.debug("读取进行中:已经读取了 " + pBytesRead + " / " + pContentLength+ " bytes.");
     fuploadStatus.setStatus("当前正在处理第" + pItems+"个文件:已经读取了 " + pBytesRead
+ " / " + pContentLength+ " bytes.");
     fuploadStatus.setReadTotalSize(pBytesRead);
     fuploadStatus.setCurrentUploadFileNum(pItems);
     fuploadStatus.setProcessRunningTime(System.currentTimeMillis());
            }
BackGroundService.storeFileUploadStatusBean(this.session,fuploadStatus);
        }

 

[1]      


--------------------next---------------------

阅读(276) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~