在项目中使用的是springmvc,在spring mvc中的上传文件的功能做的很多好,项目中使用都很方便。最近做的项目要实现上传显示上传进度,百分比;但是发现springmvc貌似没有实现这样的功能,所以就只有自己来小小的扩展一下。
springmvc中内部上传使用的是fileupload,而其实fileupload是提供了上传监控的功能的,了解了这个之后实现起来就简单了。
1. 首先跟踪一下org.springframework.web.multipart.commons.CommonsMultipartResolver这个类默认的实现,最后发现在parseRequest这个方法中能够获取到FileUpload对象
2. 创建一个类MultipartListenerResolver,继承CommonsMultipartResolver,覆盖方法parseRequest
public class MultipartListenerResolver extends CommonsMultipartResolver {
@Override
protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
//设置监听器
fileUpload.setProgressListener(new FileUploadProgressListener(request.getSession()));
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);
}
}
}
3. 创建监听器类FileUploadProgressListener,构造方法接收一个session对象,把当前上传的进度发入到session中
public class FileUploadProgressListener implements ProgressListener {
private HttpSession session;
public FileUploadProgressListener(HttpSession session) {
this.session = session;
}
//pBytesRead 已经上传的大小
//pContentLength 文件总大小
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println((double)pBytesRead/pContentLength);
session.setAttribute("progress", (double)pBytesRead/pContentLength);
}
}
4. 最后就可以直接对外提供一个接口来从session中读取上传的进度,前台通过ajax来访问