DWR3 文件上传显示进度条

最近刚开始学dwr,发现使用起来确实方便多了。现在公司正好有需求要使用文件上传,所以就研究了一下dwr3的文件上传和下载。

上传很方便,但是要显示进度条,我没找到相关的接口,我觉得dwr3应该会提供一个方便的接口用来显示进度条,后来研究dwr3的源码,发现在上传文件时,发现有下面的一段代码

if (session != null)
{
fileUploader.setProgressListener(new SessionProgressListener(session));
session.setAttribute(SessionProgressListener.CANCEL_UPLOAD, null);
session.setAttribute(PROGRESS_LISTENER, fileUploader.getProgressListener());
}


这里set了一个进度监听,并且放到session中,于是我就打算不断的从session中获取这个SessionProgressListener,然后使用dwr3推送技术,调用前台的js来改变进度条。

这就是我大概实现的思路,虽然我觉得这样很笨,但是我目前只能这样来获取上次的进度,不知道各位大侠有没有更好的办法。

下面是相关的代码:
1.前台:

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

<html>
<head>
<%@ include file="/jsp/common/include.jsp"%>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>DWR HELLO</title>
<style type="text/css">
.ProgressBar {
position: relative;
width: 350px; /* 宽度 */
border: 1px solid #B1D632;
padding: 1px;
text-align:left;
}
.ProgressBar div {
display: block;
position: relative;
background: #B1D632;
color: #333333;
height: 20px; /* 高度 */
line-height: 20px; /* 必须和高度一致,文本才能垂直居中 */
text-align:left;
}
.ProgressBar div span {
position: absolute;
width: 350px; /* 宽度 */
text-align: center;
font-weight: bold;
}
</style>

<script type='text/javascript' src='${contextPath }/dwr/engine.js'> </script>
<script type='text/javascript' src='${contextPath }/dwr/util.js'> </script>
<script type='text/javascript'
src='${contextPath }/dwr/interface/FileUpload.js'> </script>
<script type='text/javascript'
src='${contextPath }/dwr/interface/UploadListener.js'> </script>

<script type='text/javascript'
src='${contextPath }/js/dwrjs/dwrHelper.js'> </script>
<script type='text/javascript'
src='${contextPath }/js/dwrjs/upload.js'> </script>
<script type='text/javascript'
src='${contextPath }/js/zdialog/zDrag.js'> </script>
<script type='text/javascript'
src='${contextPath }/js/zdialog/zDialog.js'> </script>

<script type="text/javascript">

function addFile(){
if($("#uploadFile").val()==null || $("#uploadFile").val().length <= 0){
return ;
}
var uploadFile = dwr.util.getValue("uploadFile");
//初始化上传信息
progressBarInit($("#uploadFile").val());
//显示上传进度信息
showDialog();
//DWR3 文件上传
FileUpload.upload(uploadFile, {
callback : function(data){
Dialog.close();
$("#file_list").html($("#file_list").html()+"<a href='javascript:void(0);' onclick='downloadFile(\"" + data + "\")'>" + data + "</a><br>");
}
});
//开始监听上传数据 0.6秒推送一次
UploadListener.listener();
}
/**
**只能下载小文件,寻求解决方法
*/
function downloadFile(data) {
//alert(data);
FileUpload.download(data, function(data) {
//alert(data);
dwr.engine.openInDownload(data);
});
}

/**
**利用弹出插件,显示进度
*/
function showDialog(){

var diag = new Dialog();
diag.Width = 400;
diag.Height = 300;
diag.Title = "上传信息";
diag.InvokeElementId="upload_info" ;
diag.ShowCloseButton = false ;
//diag.OKEvent = function(){};//点击确定后调用的方法
diag.show();
}
</script>
</head>
<body onload="reverseAjax();">
<p>
<input type="file" name="uploadFile" id="uploadFile" />

<input type="button" onclick="addFile()" value="上传" />
</p>
<table>
<tr><td id="file_list"></td></tr>
</table>
<table id="upload_info" style="width:400px;text-align:left;display:none;">
<tr>
<td width="30%">上传文件名:</td>
<td><span id="upload_file_name"> </span></td>
</tr>
<tr>
<td>文件总大小:</td>
<td><span id="upload_file_size">0 KB</span></td>
</tr>
<tr>
<td>上传用时:</td>
<td><span id="upload_time">0 秒</span></td>
</tr>
<tr>
<td>上传速度:</td>
<td><span id="upload_speed">0 KB/s</span></td>
</tr>
<tr><td id="upload_text" colspan="2">文件上传中,请稍等……</td></tr>
<tr>
<td colspan="2">
<div class="ProgressBar">
<div id="progress_bar" style="width: 0%;">
<span id="progress_percent">0%</span>
</div>
</div>
</td>
</tr>
</table>
</body>
</html>



其中 upload.js 代码如下:

/**
* @zongb
*/
var $$ = function (id){return document.getElementById(id)} ;

function updateProgress(uploadInfo){

var progressPercent = Math.ceil((uploadInfo.bytesRead / uploadInfo.totalSize) * 100);
var secondsElapsed = Math.ceil(uploadInfo.deltaTime/1000);
var speed = Math.ceil(uploadInfo.bytesRead / (uploadInfo.deltaTime/1000 * 1024));

//$$('upload_file_name').innerHTML = uploadInfo.curFileName ;

$$('upload_file_size').innerHTML =Math.ceil(uploadInfo.totalSize/1024) + ' KB';

$$('upload_time').innerHTML = secondsElapsed + " 秒" ;

$$('upload_speed').innerHTML = speed + " KB/s";

$$('progress_bar').style.width = parseInt(progressPercent * 3.5) + 'px';

$$('progress_percent').innerHTML = progressPercent + "%" ;

if(progressPercent==100){
$$('upload_text').innerHTML = "处理文件中,请稍后……";
}else{
$$('upload_text').innerHTML = "文件上传中,请稍等……";
}

}
/**
* 初始化上传信息
*/
function progressBarInit(uploadFile){

var filename = uploadFile.substring(uploadFile.lastIndexOf("\\")+1,uploadFile.length) ;

$$('upload_file_name').innerHTML = filename ;

$$('upload_file_size').innerHTML ='0 KB';

$$('upload_time').innerHTML = "0 秒" ;

$$('upload_speed').innerHTML = "0 KB/s";

$$('progress_bar').style.width = '0px';

$$('progress_percent').innerHTML = "0%" ;
}

function reverseAjax() {
dwr.engine.setActiveReverseAjax(true);
}




dwrHelper.js只是一个针对dwr3错误处理
zDrag.js 和 zDialog.js 是用的一个弹出框插件,附件中会列出的

2.然后是dwr3的配置文件(web.xml怎么配置的我就不写了)

<create creator="new" javascript="FileUpload">
<param name="class" value="com.method.dwr.Upload"/>
</create>
<create creator="new" javascript="UploadListener" scope="script">
<param name="class" value="com.method.dwr.TestProgress"/>
</create>
<convert converter="bean" match="com.method.dwr.util.fileUpload.ProgressInfo"/>




3.java代码
供前台调用的类

package com.method.dwr;


import org.apache.log4j.Logger;
import org.directwebremoting.io.FileTransfer;

import com.method.dwr.util.exception.ExceptionValidate;
import com.method.dwr.util.fileUpload.FileUpload;
import com.method.dwr.util.fileUpload.ProgressInfo;


public class Upload {

public static Logger log = Logger.getLogger(Upload.class) ;

private ProgressInfo pi = null;

private FileUpload upload = null ;
/**
* DWR 单文件上传
* 页面编码必须使用GBK,否则上传文件名为中文时,会出现乱码
* @return
* @throws Exception
*/
public String upload(FileTransfer fileTransfer) throws Exception {
log.info("=======================") ;
upload = new FileUpload();
return upload.upload(fileTransfer,50,"/upload");
}

/**
* 文件下载
* 在IE下,中文文件名会有乱码出现,待解决。
* @param fileName
* @return
* @throws Exception
*/
public FileTransfer download(String fileName) throws Exception{
upload = new FileUpload();
return upload.download(fileName,"/upload");
}
}




dwr3上传文件的类

package com.method.dwr.util.fileUpload;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.apache.log4j.Logger;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.io.FileTransfer;

import com.method.dwr.util.exception.ExceptionValidate;


public class FileUpload {

public static Logger log = Logger.getLogger(FileUpload.class) ;

private WebContext wctx = null;
/**
* DWR 单文件上传
* 页面编码必须使用GBK,否则上传文件名为中文时,会出现乱码
* @param fileTransfer
* @param maxSizeWithM 允许上传的最大文件
* @param savePath 文件保存的路径(/upload)
* @return
* @throws Exception
*/
public String upload(FileTransfer fileTransfer,int maxSizeWithM,String savePath) throws Exception {

if(maxSizeWithM != 0 && fileTransfer.getSize() > 1024*1024*maxSizeWithM){
//throw new ExceptionValidate("提示:您上传的单个文件不能超过" + maxSizeWithM + "M !") ;
}

wctx = WebContextFactory.get();

log.info("----------"+fileTransfer.getSize()) ;

//存储的绝对路径
String saveurl = wctx.getHttpServletRequest().getSession()
.getServletContext().getRealPath(savePath);

log.info("----------" + saveurl) ;

String fileName = new String(fileTransfer.getFilename().getBytes(),"GBK");
//文件名
fileName = fileName.substring(fileName.lastIndexOf(java.io.File.separator)+1) ;

log.info("-------fileName---" + fileName) ;

File file = new File(saveurl + java.io.File.separator + fileName);

if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}

//开始读取文件
byte[] bytes = new byte[1024*10];

FileOutputStream foutput = new FileOutputStream(file);

BufferedOutputStream Buff = new BufferedOutputStream(foutput);

InputStream fis = fileTransfer.getInputStream();

int len=0;
while((len=fis.read(bytes))>0)
{
Buff.write(bytes,0,len);

}
Buff.flush();
Buff.close();
foutput.close();
fis.close();

log.info("-----文件上传结束-----") ;
return fileName;
}

/**
* 文件下载
* 在IE下,中文文件名会有乱码出现,待解决。
* @param fileName
* @return
* @throws Exception
*/
public FileTransfer download(String fileName,String savePath) throws Exception{


wctx = WebContextFactory.get();
// String realtivepath = webContext.getServletContext().getContextPath()
// + "/upload/";

log.info("-------fileName-1111--" + fileName) ;

String saveurl = wctx.getHttpServletRequest().getSession()
.getServletContext().getRealPath(savePath);
if (fileName == null || fileName.length() == 0) {
fileName = "[BLANK]";
}
BufferedInputStream in;
try {
in = new BufferedInputStream(new FileInputStream(saveurl + java.io.File.separator + fileName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
throw new ExceptionValidate("您要下载的文件:[" + fileName + "]不存在!");
}

ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] temp = new byte[1024*10];
int size = 0;
while ((size = in.read(temp)) != -1)
{
out.write(temp, 0, size);
}

//log.info(new String(out.toByteArray(),"ISO8859-1"));
return new FileTransfer(new String(fileName.getBytes("UTF-8"),"ISO8859-1"),null,out.toByteArray());

}
}




这个是存储进度条信息的类


package com.method.dwr.util.fileUpload;

import java.util.ArrayList;


public class ProgressInfo
{
private long totalSize = 0;
private long bytesRead = 0;
private int fileIndex = 0;
private long startTime = System.currentTimeMillis();
private long deltaTime = 0;
private String uploadedFiles = "";

private boolean isInProgress = true;
private boolean isCompleted = false;

private String curFileName = "";
private String errorMsg = "";


public String getErrorMsg() {
return errorMsg;
}

public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}

public String getCurFileName() {
return curFileName;
}

public void setCurFileName(String curFileName) {
this.curFileName = curFileName;
}

public String getUploadedFiles() {
return uploadedFiles;
}

public void setUploadedFiles(String uploadedFiles) {
this.uploadedFiles = uploadedFiles;
}

public long getStartTime() {
return startTime;
}

public void setStartTime(long startTime) {
this.startTime = startTime;
}

public void setDeltaTime(long deltaTime) {
this.deltaTime = deltaTime;
}

public ProgressInfo()
{
}

public long getTotalSize()
{
return totalSize;
}

public void setTotalSize(long totalSize)
{
this.totalSize = totalSize;
}

public long getBytesRead()
{
return bytesRead;
}

public void setBytesRead(long bytesRead)
{
this.bytesRead = bytesRead;
}

public long getDeltaTime()
{
return System.currentTimeMillis() - this.startTime;
}

public boolean isInProgress()
{
return isInProgress;
}

public int getFileIndex()
{
return fileIndex;
}

public void setFileIndex(int fileIndex)
{
this.fileIndex = fileIndex;
}

public boolean isCompleted() {
return isCompleted;
}

public void setCompleted(boolean isCompleted) {
this.isCompleted = isCompleted;
this.isInProgress = false;

}

public void setInProgress(boolean isInProgress) {
this.isInProgress = isInProgress;
}
}




上面的方法中,有dwr3的下载方法,我的理解是,这个下载方法,是先把文件一次读取到内存中,再在页面中提供下载,这样有个问题:无法下载大文件,不知道各位有没有更好的方法

如果大家有什么更好的建议,希望能提出来,大家一起分享

谢谢!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值