extjs+springmvc上傳文件顯示進度條

    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

相關文章
相關標籤/搜索