Ajax Upload--文件上传进度条
1.概述
Ajax Upload 实现了文件上传进度条的功能。
首先简要说明一下AjaxUpload的原理:我们知道上传文件的时候实际上是客户端和服务器端创建了一个文件流,我们的目标就是实时得到这个文件到底上传了多少。我们只要在服务器端创建一个监听器监听这个文件流,很容易就能得到上传的大小,关键问题是怎么把当前一上传的大小返回给客户端显示出来。有了AJAX,这个还是问题么?用DWR 远程调用服务端的FileUploadMontor取一下就OK了。
SpringSide在BookStore示例的图书管理中演示了该技术。
2. 使用
2.1 所需文件
1.SpringSide Core 的Ajax Upload部分java文件,由网上源码摘抄并修改而来。
2. BookStore 中的的webapp/widgets/ajaxupload目录的js与css 文件
3. DWR配置文件,负责与上传状态类的通信。
2.2 与Struts框架的结合
网上的源码已经做好了实现。我们要做的就是在struts上传的组件中加一个监听器。Struts是使用commons-upload来上传的,整合起来比较方便。只需要自己实现一个MultipartRequestHandler,加入监听器的功能,替换掉默认的版本就可以了。
修改Struts使用的MultipartRequestHandler的方法是在配置文件里加入controller:
<controller> <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/> <set-property property="multipartClass" value="org.springside.core.components.ajaxupload.AjaxMultipartRequestHandler"/> </controller>
大功告成!!
2.3 DWR的配置
主要配置DWR 输出UploadMonitor的内容,见bookstore中的WEB-INF/dwr.xml 和web.xml 中引入dwr的部分,参考DWR 中的描述。
2.4 Struts Action 无需修改
action跟正常的文件上传是一样的,就是从frombean里得到文件,然后IO处理就是了,这里就不重复了。
2.5 页面的修改
页面需要加上css和ajaxupload.js脚本, dwr的js脚本,还有特定的div来显示进度条的效果。
如果直接使用我们的封装的css和js,请在jsp页面直接引用
<%@ include file="/widgets/ajaxupload/ajaxupload.jsp" %>
1.其中css文件指定了进度条的大小和颜色:
#progressBar { padding-top: 5px; } #progressBarBox { width: 350px; height: 20px; border: 1px inset; background: #eee; } #progressBarBoxContent { width: 0; height: 20px; border-right: 1px solid #444; background: #9ACB34; text-align: right; }
2.js文件的内容:
var fileInput; var submitButton; var progressBarBoxContent; var progressBar; function refreshProgress() { UploadMonitor.getUploadInfo(updateProgress); } function updateProgress(uploadInfo) { if (uploadInfo.inProgress) { progressBar.style.display = 'block'; fileInput.style.display = 'none'; fileInput.disabled = true; submitButton.disabled = true; var fileIndex = uploadInfo.fileIndex; var progressPercent = Math.ceil((uploadInfo.bytesRead / uploadInfo.totalSize) * 100); progressBarBoxContent.innerHTML = progressPercent + '%'; progressBarBoxContent.style.width = parseInt(progressPercent * 3.5) + 'px'; window.setTimeout('refreshProgress()', 100); } else { submitButton.disabled = false; fileInput.disabled = false; progressBar.style.display = 'none'; } return true; } function startProgress(fileInputName, submitButtonName) { fileInput = document.getElementById(fileInputName); submitButton = document.getElementById(submitButtonName); progressBar = document.getElementById('progressBar'); progressBarBoxContent = document.getElementById('progressBarBoxContent'); if (fileInput /!= null && submitButton /!= null && progressBar /!= null && progressBarBoxContent /!= null) { progressBarBoxContent.innerHTML = '0%'; window.setTimeout("refreshProgress()", 150); return true; } else { alert('Ajax Upload ERROR/!'); return false; } }
3. 加入进度条的div,见bookstore示例中的bookform.jsp
4. form的onsubmit事件
在form的onsubmit事件里,要加上startProgress才能显示上传进度条。
οnsubmit="return validateBookForm(this) && startProgress('imageFile','save')"