Ext4.2结合Spring MVC实现文件上传显示进度

1.实现原理:

  在大文件上传时显示上传进度是很有必要的,不能让用户感觉到陷入无穷的等待中,或感觉程序已经卡死。为此我们可以在session中存一个上传进度的变量,在文件上传的过程中实时的去修改这个值,这就需要在后台重写Spring MVC自带的上传解析类,每上传一定的字节数就修改一下session中的进度,在前台通个AJAX请求每隔一定的时间去获取这个值显示给用户,这样就达到了显示上传进度的需求,不过这样频繁的请求服务器无疑是增加了服务器的压力,在没有使用任何第三方上传组件的情况下只能如此。

2.测试结果:

没有出现任何内存溢出或奔溃的情况。

前台效果和后台打印日志:

3.代码

 ①CustomMultipartResolver.java,Spring默认的文件上传类是CommonsMultipartResolver,我们需要自定义一个类CustomMultipartResolver继承它.

package com.upload;

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;

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

}

②spring-servlet.xml,XML配置

<!-- 文件上传配置 -->
    <!-- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
         <property name="maxUploadSize" value="1048576000"/>
         <property name="maxInMemorySize" value="4096"/>
         <property name="defaultEncoding" value="UTF-8"></property>
    </bean>
   -->
    <bean id="multipartResolver" class="com.upload.CustomMultipartResolver">
         <property name="maxUploadSize" value="1048576000"/>
         <property name="maxInMemorySize" value="4096"/>
         <property name="defaultEncoding" value="UTF-8"></property>
    </bean> 

③MyProgressListener.java,文件上传监听器,需要实现ProgressListener接口

package com.upload;

import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.ProgressListener;

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);
       // System.out.println("当前进度:"+ps.getpBytesRead());
    }
}

④ProgressEntity.java 包含上传信息的实体

package com.upload;

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 + "]";
    }
}

⑤Action中的方法,上传方法任然不用变,还是原来的Spring上传方法,只需修改XML中的上传解析器.改成前面自定义的即可,增加一个获取上传进度的方法。SuccessBean是封装了返回前台的信息:包含success和msg两个字段。

@ResponseBody
    @RequestMapping(value = "/getProgress", method = RequestMethod.GET)
    public SuccessBean getProgress(HttpServletRequest request, HttpServletResponse response){
        if(request.getSession().getAttribute("upload_ps")==null){
             return new SuccessBean(true,"0");
        }
        ProgressEntity ps = (ProgressEntity)request.getSession().getAttribute("upload_ps");
        Double percent = 0d;
        if(ps.getpContentLength() != 0L){
            percent = (double)ps.getpBytesRead()/(double)ps.getpContentLength()*1.0d;  //百分比
            if(percent != 0d){
                DecimalFormat df = new DecimalFormat("0.00");
                percent = Double.parseDouble(df.format(percent));
            }
        }
       logger.info("当前上传进度:" + percent.toString());
       return new SuccessBean(true, percent.toString());
    }

⑥前台就更简单了,只需一个FormPanel添加一个filefield组件,在表单提交后同时启动定时任务,每隔1秒从后台获取一下进度显示出来即可。

时间: 2024-10-11 16:45:54

Ext4.2结合Spring MVC实现文件上传显示进度的相关文章

Spring MVC 多文件上传大小限制及异常处理

Spring MVC  多文件上传大小限制及异常处理 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 在 spring mvc 的默认配置文件 WEB-INF/xxx-servlet.xml 中

【Spring学习笔记-MVC-13】Spring MVC之文件上传

作者:ssslinppp       1. 摘要 Spring MVC为文件上传提供了最直接的支持,这种支持是通过即插即用的MultipartResolve实现的.Spring使用Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver. 下面将具体讲解Spring MVC实现文件上传的具体步骤. 2. 添加Jar包 Spring MVC文件上传,需要添加如下两个jar包: commons-fil

spring mvc ajaxfileupload文件上传返回json下载问题

问题:使用spring mvc ajaxfileupload 文件上传在ie8下会提示json下载问题 解决方案如下: 服务器代码: @RequestMapping(value = "/addAnalysis", method = RequestMethod.POST) public void addAnalysisUI( HttpServletResponse response,HttpServletRequest request,HttpSession session, @Requ

spring mvc注解文件上传下载

需要两个包: 包如何导入就不介绍了,前端代码如下(一定要加enctype="multipart/form-data"让服务器知道是文件上传): <form action="upload.do" method="post" enctype="multipart/form-data"> <input type="file" id="upimage" name="f

Spring MVC实现文件上传和下载

本篇博客将讲解的是Springmvc的文件上传和下载功能.对于上传功能,我们在项目中是经常会用到的,比如用户注册的时候,上传用户头像,这个时候就会使用到上传的功能.而对于下载,使用场景也很常见,比如我们项目中有个使用说明是是pdf版的,会提供给用户进行下载的功能.相对于来说,这两个功能都是很常见,废话不多说,按照惯例,我们先来看一下本篇博客的目录. 目录 一:搭建SpringMvc开发环境 二:实现文件上传的功能 三:将上传文件绑定到具体的对象上 四 : 实现用户下载的功能 五:总结 一:搭建S

java之spring mvc之文件上传

目录结构如下: 注意,下面说的配置文件,一般都是值的src下的配置文件,即mvc.xml.如果是web.xml,则直接说 web.xml 1. 文件上传的注意点 表单必须是post提交,必须将 enctype 设置为 “multipart/form-data”, 使用 commons-fileupload 提交文件,需要添加 commons-fileupload 和 commons-io 的 jar 包. 2.Jsp 页面 <form action="file/upload.do"

Spring MVC 之文件上传(七)

SpringMVC同样使用了apache的文件上传组件.所以需要引入以下包: apache-commons-fileupload.jar apache-commons-io.jar 在springAnnotation-servlet.xml中配置 1 <!-- 定义文件上传解析器 --> 2 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.Common

spring mvc CommonsMultipartResolver文件上传maxUploadSize限制大小

第一步:配置sping Xml代码   <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--1024*200即200k--> <property name="maxUploadSize" value="204800"/> <

spring test---restful与文件上传

spring提供了大量经常使用的功能測试,如文件上传.restful风格url訪问.以下介绍主要介绍下test中经常使用功能的使用方法: 首先能够静态导入类.方便在測试类中使用,导入的类有 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockR