首先Spring是一个非常成熟的J2EE框架,其非入侵式的架构为系统的集成和扩展提供了最大的可能。所以Spring MVC下实现进度监听非常容易,甚至不需要改以前的上传业务代码,具体实现分三个步骤:
1、接管CommonsMultipartResolver,重写针对文件上传的请求。
2、在第一步中写入监听,以获取上传进度。
3、修改上传部分的配置文件。
具体见代码
1、CommonsMultipartResolver代码
package com.van.utils.upload.handle;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.FileUpload;import org.apache.commons.fileupload.FileUploadBase;import org.apache.commons.fileupload.FileUploadException;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 com.van.utils.upload.listener.PJProgressListener;/** * 重写CommonsMultipartResolver以监听文件上传进度 * @author Van * @date 2012-12-12 */public class PJCommonsMultipartResolver extends CommonsMultipartResolver { private HttpServletRequest request; protected FileUpload newFileUpload(FileItemFactory fileItemFactory) { ServletFileUpload upload = new ServletFileUpload(fileItemFactory); upload.setSizeMax(-1); if (request != null) { HttpSession session = request.getSession(); PJProgressListener uploadProgressListener = new PJProgressListener(session); upload.setProgressListener(uploadProgressListener); } return upload; } public MultipartHttpServletRequest resolveMultipart( HttpServletRequest request) throws MultipartException { this.request = request;// 获取到request,要用到session return super.resolveMultipart(request); } @SuppressWarnings("unchecked") @Override public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { HttpSession session = request.getSession(); String encoding = "utf-8"; FileUpload fileUpload = prepareFileUpload(encoding); PJProgressListener uploadProgressListener = new PJProgressListener(session); fileUpload.setProgressListener(uploadProgressListener); try { List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadException ex) { throw new MultipartException("Could not parse multipart servlet request", ex); } }}
PJProgressListener 代码:
package com.van.utils.upload.listener;import javax.servlet.http.HttpSession;import org.apache.commons.fileupload.ProgressListener;import com.van.utils.upload.entity.ProgressEntity;public class PJProgressListener implements ProgressListener{ private HttpSession session; public PJProgressListener() { } public PJProgressListener(HttpSession _session) { session=_session; ProgressEntity ps = new ProgressEntity(); session.setAttribute("upload_ps", ps); } public void update(long pBytesRead, long pContentLength, int pItems) { ProgressEntity ps = (ProgressEntity) session.getAttribute("upload_ps"); ps.setpBytesRead(pBytesRead); ps.setpContentLength(pContentLength); ps.setpItems(pItems); //更新 session.setAttribute("upload_ps", ps); }}
上传进度信息记录实体类:
package com.van.utils.upload.entity;/** * 文件上传进度信息 * @author Van * */public class ProgressEntity { 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 + "]"; }}
配置文件部分修改:
<!-- 文件上传支持 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <!-- 内存缓存1M --> <property name="maxInMemorySize" value="1000000"></property> <!-- 最大2GB --> <property name="maxUploadSize" value="2000000000" ></property> </bean>
将org.springframework.web.multipart.commons.CommonsMultipartResolver替换成:com.van.utils.upload.handle.PJCommonsMultipartResolver