文档章节

extjs+springmvc上传文件显示进度条

hold_the_line
 hold_the_line
发布于 2014/04/10 09:35
字数 871
阅读 1133
收藏 4

    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中保存文件上传进度实体类).

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);
        
    }

    文件上传进度写了个实体类封装ProgressEntity

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类

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写的一个简单的请求。

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中的进度。

/**
     * 前端每隔固定毫秒数请求后台得到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()));
    }

    大致是这样,只为记录,不想几年后什么都没留下就走了。

© 著作权归作者所有

共有 人打赏支持
hold_the_line
粉丝 0
博文 6
码字总数 1956
作品 0
深圳
HTML5矢量实现文件上传进度条

在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传、上传成功了没有,所以今天给大家介绍的内容是通过HT for Web矢量来实现HTML5...

xhload3d
2015/11/22
248
1
基于HT for Web矢量实现HTML5文件上传进度条

在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传、上传成功了没有,所以今天给大家介绍的内容是通过HT for Web矢量来实现HTML5...

xhload3d
2015/06/08
0
0
Linux下使用GTK+创建窗口关闭后,再创建时候提示窗口已经存在

我在linux redhat7.5下发使用GTK+开发窗口显示界面。 主要是文件上传下载操作。 首先,进程中创建一个UI线程主要接收命令文件上传下载命令消息。 再创建一个GTK界面绘制线程,此GTK线程创建一...

lover2668
09/19
0
0
js的XMLHttpRequest做文件上传进度条问题

XMLHttpRequest 做文件上传进度条显示 xhr.upload.addEventListener("progress", uploadProgress, false); 这个监控到的进度条是真实的上传进度条么? 疑问1:为什么上传完成后服务器要过会才...

那天早上
2013/11/08
4.6K
3
一些文件上传组件(Flash,JQuery,asp,php,js,AJAX)

FancyUpload FancyUpload是一个采用Flash与Ajax(MooTools)技术实现包含上传进度条的多文件上传组件,类似于SWFUpload。 FancyUpload Mootools jqUploader 结合Javascript与Flash开发,拥有...

老朱教授
2017/10/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
29分钟前
0
0
AVA中CAS-ABA的问题解决方案AtomicStampedReference

了解CAS(Compare-And-Swap) CAS即对比交换,它在保证数据原子性的前提下尽可能的减少了锁的使用,很多编程语言或者系统实现上都大量的使用了CAS。 JAVA中CAS的实现 JAVA中的cas主要使用的是...

码代码的小司机
32分钟前
1
0
Android JNI开发系列(十三) JNI异常处理

JNI 异常处理 JNI异常与JAVA处理异常的区别 JAVA 有异常处理机制,而JNI没有 如果JAVA中异常没有捕获,后面的代码不会执行,JNI会执行 JAVA编译时的异常,是在方法显示的声明了某一个异常,编...

蔡小鹏
45分钟前
2
0
简单介绍Java 的JAR包、EAR包、WAR包区别

WAR包 WAR(Web Archive file)网络应用程序文件,是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。War专用于Web方面。大部分的JAVA WEB工程,都是打成WAR包进行发布的。 War是...

Linux就该这么学
今天
1
0
Qt那些事0.0.7

在帮助文档(Overview - QML and C++ Integration)中随缘遇到一张图,是关于C++对象与QML整合介绍的,值得标记下来,虽然大部分功能也有所涉猎,但是还是留个记号,万一哪天我失忆了还想写Q...

Ev4n
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部