最近刚开始学dwr,发现使用起来确实方便多了。现在公司正好有需求要使用文件上传,所以就研究了一下dwr3的文件上传和下载。
上传很方便,但是要显示进度条,我没找到相关的接口,我觉得dwr3应该会提供一个方便的接口用来显示进度条,后来研究dwr3的源码,发现在上传文件时,发现有下面的一段代码
这里set了一个进度监听,并且放到session中,于是我就打算不断的从session中获取这个SessionProgressListener,然后使用dwr3推送技术,调用前台的js来改变进度条。
这就是我大概实现的思路,虽然我觉得这样很笨,但是我目前只能这样来获取上次的进度,不知道各位大侠有没有更好的办法。
下面是相关的代码:
1.前台:
其中 upload.js 代码如下:
dwrHelper.js只是一个针对dwr3错误处理
zDrag.js 和 zDialog.js 是用的一个弹出框插件,附件中会列出的
2.然后是dwr3的配置文件(web.xml怎么配置的我就不写了)
3.java代码
供前台调用的类
dwr3上传文件的类
这个是存储进度条信息的类
上面的方法中,有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的下载方法,我的理解是,这个下载方法,是先把文件一次读取到内存中,再在页面中提供下载,这样有个问题:无法下载大文件,不知道各位有没有更好的方法
如果大家有什么更好的建议,希望能提出来,大家一起分享
谢谢!