SpringMVC上傳文件用的是CommonsMultipartResolver配置在xx-servlet.xml中,當上傳大文件時,向後臺發送請求,此時的request被spring解析爲DefaultMultipartHttpServletRequest。前端
@RequestMapping(value = "/uploadVideo1", method = RequestMethod.POST) public void uploadVideo1(@RequestParam MultipartFile file,HttpServletRequest request, HttpServletResponse response) throws Exception { String contextPath = request.getSession().getServletContext().getRealPath(Common.uploadPath); this.fileUpload(contextPath, file, response); } private void fileUpload(String contextPath, MultipartFile file, HttpServletResponse response){ File filepath = new File(contextPath); logger.info("上傳文件名[" + file.getName() + "],文件大小[" + file.getSize() + "]"); if (!filepath.exists()) { filepath.mkdir(); logger.info("[" + filepath.getAbsolutePath() + "]建立成功!"); } try { int index = file.getOriginalFilename().lastIndexOf("."); long timestamp = System.currentTimeMillis(); String orgFileName = timestamp + file.getOriginalFilename().substring(index); File orgFile = new File(contextPath, orgFileName); file.transferTo(orgFile); logger.info("[" + orgFileName + "]保存成功!"); /*保存文件對象信息,自定義的類*/ FileManager fileManager = new FileManager(); String date = StrUtils.formateDate("yyyy-MM-dd HH:mm:ss", new Date()); fileManager.setFname(Common.CENTER_WEBSITE + "/" + Common.uploadPath + "/" + orgFileName); fileManager.setDate(date); fileManagerBiz.saveFileManager(fileManager); logger.info("[" + orgFileName + "]上傳成功!"); super.outJson(response, new JSONResult(true, Common.CENTER_WEBSITE + "/" + Common.uploadPath + "/" + orgFile.getName())); } catch (Exception e) { logger.info("Exception異常:" + e.getLocalizedMessage()); super.outJson(response, new JSONResult(false, "上傳失敗")); } }
須要一個監聽器去監聽文件的上傳進度.所以寫一個類實現ProgressListener(在session中保存文件上傳進度實體類).java
public class MyProgressListener implements ProgressListener { private HttpSession session; public MyProgressListener() { } public MyProgressListener(HttpSession session) { this.session = session; ProgressEntity ps = new ProgressEntity(); session.setAttribute("upload_ps", ps); } public void setSession(HttpSession session){ this.session = session; } @Override 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); }
文件上傳進度寫了個實體類封裝ProgressEntityspring
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 + "]"; }
要實現文件的監聽,須要重寫spring的CommonsMultipartResolver類session
public class CustomMultipartResolver extends CommonsMultipartResolver { private HttpServletRequest request; protected FileUpload newFileUpload(FileItemFactory fileItemFactory) { ServletFileUpload upload = new ServletFileUpload(fileItemFactory); if (request != null) { HttpSession session = request.getSession(); MyProgressListener uploadProgressListener = new MyProgressListener(session); upload.setProgressListener(uploadProgressListener); } return upload; } public MultipartHttpServletRequest resolveMultipart( HttpServletRequest request) throws MultipartException { this.request = request;// 獲取到request,要用到session return super.resolveMultipart(request); } @Override public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException { String encoding = determineEncoding(request); FileUpload fileUpload = prepareFileUpload(encoding); //設置監聽器 MyProgressListener progressListener = new MyProgressListener(request.getSession()); fileUpload.setProgressListener(progressListener); 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); } } }
由於是用extjs4.2寫的一個簡單的請求。app
var p = Ext.Msg.show({ title:'上傳進度', progress:true, width:300 }); p.updateProgress(0,'0%'); /*mask.show();*/ Eform.getForm().submit({ url : 'public/uploadVideo1?t='+new Date(), clientValidation: true, success: function(form, action) { if (action.result.success) { field.setValue(action.result.message); form.reset(); Ewindow.hide(); p.hide(); } else { Ext.Msg.alert('提示','<p align="center">'+action.result.message+'</p>'); } Ewindow.hide(); }, failure: function(form, action) { switch (action.failureType) { case Ext.form.action.Action.CLIENT_INVALID: break; case Ext.form.action.Action.CONNECT_FAILURE: Ext.Msg.alert('提示', '<p align="center">通訊失敗,請稍後再試或聯繫管理員</p>'); break; case Ext.form.action.Action.SERVER_INVALID: Ext.Msg.alert('提示', '<p align="center">' + action.result.message + '</p>'); } /*mask.hide();*/ Ewindow.hide(); } }); var percent;//上傳進度百分比 //定時器每隔100毫秒請求獲得session中的進度 var timer = setInterval(function(){ Ext.Ajax.request({ url:'public/getProgress?t='+new Date(), method:'get', success: function(response) { var result = Ext.decode(response.responseText); console.log(result); if(result.success){ percent = result.message; p.updateProgress(percent,percent*100+'%'); if(percent >= 1.0){//進度爲100%之後,取消定時器 clearInterval(timer); } }else{ Ext.Msg.alert('提示',result.message); } } }); },100); }
請求的方法只是簡單的取出session中的進度。ide
/** * 前端每隔固定毫秒數請求後臺獲得session當中保存的上傳進度 * @param request * @param response */ @RequestMapping(value = "/getProgress", method = RequestMethod.GET) public void getProgress(HttpServletRequest request, HttpServletResponse response){ ProgressEntity ps = (ProgressEntity)request.getSession().getAttribute("upload_ps"); Double percent = 0d; if(ps.getpContentLength() != 0L){ percent = (double)ps.getpBytesRead()/(double)ps.getpContentLength(); //百分比 if(percent != 0d){ DecimalFormat df = new DecimalFormat("0.0"); percent = Double.parseDouble(df.format(percent)); } } this.outJson(response, new JSONResult(true, percent.toString())); }
大體是這樣,只爲記錄,不想幾年後什麼都沒留下就走了。
this