1、 接管CommonsMultipartResolver,重写针对文件上传的请求。
package com.sinosoft.amoeba.fileupload;
import com.sinosoft.amoeba.fileupload.listener.FileUploadProgressListener;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* 重写CommonsMultipartResolver以监听文件上传进度
* @author gf
* @date 2016-12-2
*/
public class CustomMultipartResolverextends CommonsMultipartResolver {
privateHttpServletRequest request;
protectedFileUpload newFileUpload(FileItemFactory fileItemFactory) {
ServletFileUpload upload = new ServletFileUpload(fileItemFactory);
upload.setSizeMax(-1);
if (request != null) {
HttpSession session = request.getSession();
FileUploadProgressListenerprogressListener = new FileUploadProgressListener(session);
upload.setProgressListener(progressListener);
}
returnupload;
}
publicMultipartHttpServletRequest resolveMultipart(HttpServletRequestrequest) throws MultipartException{
// 获取到request,要用到session
this.request =request;
returnsuper.resolveMultipart(request);
}
@Override
publicMultipartParsingResult parseRequest(HttpServletRequest request)throws MultipartException {
HttpSession session =request.getSession();
String encoding =determineEncoding(request);
FileUpload fileUpload =prepareFileUpload(encoding);
FileUploadProgressListenerprogressListener = new FileUploadProgressListener(session);
fileUpload.setProgressListener(progressListener);
try {
List<FileItem> fileItems =((ServletFileUpload) fileUpload).parseRequest(request);
returnparseFileItems(fileItems, encoding);
} catch(FileUploadBase.SizeLimitExceededException ex) {
thrownew MaxUploadSizeExceededException(fileUpload.getSizeMax(),ex);
} catch(FileUploadException ex) {
thrownew MultipartException("Could not parse multipart servlet request", ex);
}
}
}
2、 写入监听,获取记录上传进度
package com.sinosoft.amoeba.fileupload.listener; import com.sinosoft.amoeba.fileupload.model.Progress;import org.apache.commons.fileupload.ProgressListener; import javax.servlet.http.HttpSession; /** * * 创建人:gf * 创建时间:2016-12-1 <br> * 功能描述: 文件上传进度<br> */public class FileUploadProgressListener implements ProgressListener { private HttpSession session; public FileUploadProgressListener() { } public FileUploadProgressListener(HttpSession session) { this.session=session; Progress status = new Progress(); session.setAttribute("upload_ps", status); } /** * pBytesRead 到目前为止读取文件的比特数 pContentLength 文件总大小 pItems 目前正在读取第几个文件 */ private long old=0; public void update(long pBytesRead, long pContentLength, int pItems) { Progress status = (Progress) session.getAttribute("upload_ps"); status.setpBytesRead(pBytesRead); status.setpContentLength(pContentLength); status.setpItems(pItems); //System.out.println("已经传送了:"+pBytesRead+"--------------文件总大小为:"+pContentLength+"-----第"+pItems+"个"); /*System.out.println("文件总大小为:"+pContentLength);*/ if(old>pBytesRead) { String a=""; }else { old=pBytesRead; } session.setAttribute("upload_ps", status); }}
3、 通过Progress类接收上传文件参数
package com.sinosoft.amoeba.fileupload.model; /** * * 创建人:gf <br> * 创建时间:2016-12-2 <br> * 功能描述: 文件上传进度<br> */public class Progress { private long pBytesRead = 0L; private long pContentLength = 0L; private int pItems; public long getpBytesRead() { return pBytesRead; } public void setpBytesRead(long pBytesRead) { this.pBytesRead = pBytesRead; } public long getpContentLength() { return pContentLength; } public void setpContentLength(long pContentLength) { this.pContentLength = pContentLength; } public int getpItems() { return pItems; } public void setpItems(int pItems) { this.pItems = pItems; } @Override public String toString() { return "ProgressEntity [pBytesRead=" + pBytesRead + ", pContentLength=" + pContentLength + ", pItems=" + pItems + "]"; } }
4、 配置XML文件
<!--文件上传监听--><bean id="multipartResolver" class="com.sinosoft.amoeba.fileupload.CustomMultipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <!-- 内存缓存1M --> <property name="maxInMemorySize" value="1000000"></property> <!--这里限制了上传最大数 在程序中需要控制 否在总大小为-1了就 超出了--> <property name="maxUploadSize" value="10147483648"/></bean>
5、 获取监听数据以及进度条展示
Jsp代码:
<label id="progress" style="position: relative;left: 10px;top:5px "> 保存进度: <div id="proBack" style="width: 400px;height: 5px;margin-top:-10px;margin-left:60px;background:gray;"> <div id="proUp" style="width: 0px;height: 5px;background:red;"> </div> </div> <label id="progressId" style="margin-left: 465px;position: relative;top: -11px"></label></label>
Js代码
//放到上传文件时候
setInterval(getProgress,100);
// getProgress方法
function getProgress() { $.ajax({ url:ctx+"/compact/getProgress", type:"get", dataType:"text", async: false, success:function(data) { var backGroundWidth = $("#proBack").width(); var proUpWidth = (backGroundWidth*data.replace("%",""))/100; $("#proUp").width(proUpWidth); $("#progressId").text(data); if(data==‘100%‘) { upFile=false; } }, error:function(data) { msgAlert("系统消息","出错了!"); } });}
java代码:
Progress status = (Progress) request.getSession().getAttribute("upload_ps");
//已上传字节数
status.getpBytesRead();
//总字节数
status.getpContentLength()
//根据需要返回上传百分比即可
但是这种情况对服务器访问次数太多,用户太多或者服务器性能不好这么做不太好。
另一种实现方式为做一个假的进度条或者转动的圆圈,当文件没有上传成功就一直转,上传成功,弹出保存成功,即可