springboot 文件上传进度

Spring Boot 提供了多种文件上传的方式,其中最常用的方式是使用 Spring MVC 提供的 MultipartResolver 来处理文件上传请求。

要在 Spring Boot 中实现文件上传进度的功能,可以借助于第三方的文件上传组件,例如 Apache Commons FileUpload 和 Servlet 3.0 的 Part 接口。

具体实现步骤如下:

  • 在 Spring Boot 中引入 Apache Commons FileUpload 和 IO 依赖:
  • <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.8.0</version>
    </dependency>
    
  • 配置 MultipartResolver:
  • @Bean
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setMaxUploadSize(5242880); // 设置最大上传文件大小为 5MB
        return resolver;
    
  • 创建自定义的 MultipartHttpServletRequestWrapper 类,用于封装 HttpServletRequest 并添加获取文件上传进度的方法:
  • public class MultipartHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private final ProgressListener progressListener;
        public MultipartHttpServletRequestWrapper(HttpServletRequest request, ProgressListener progressListener) {
            super(request);
            this.progressListener = progressListener;
        @Override
        public ServletInputStream getInputStream() throws IOException {
            return new ProgressInputStream(super.getInputStream(), progressListener);
        public long getBytesRead() {
            ProgressInputStream progressInputStream = (ProgressInputStream) getInputStream();
            return progressInputStream.getBytesRead();
    

    其中 ProgressListener 和 ProgressInputStream 用于监听上传进度和统计已上传的字节数,具体实现可以参考 Apache Commons FileUpload 的文档。

  • 在控制器中获取上传进度:
  • @PostMapping("/upload")
    public ResponseEntity<String> upload(HttpServletRequest request) throws Exception {
        ProgressListener progressListener = new MyProgressListener();
        MultipartHttpServletRequestWrapper multipartRequest = new MultipartHttpServletRequestWrapper((HttpServletRequest) request, progressListener);
        MultipartResolver resolver = new CommonsMultipartResolver();
        MultipartHttpServletRequest multipartHttpServletRequest = resolver.resolveMultipart(multipartRequest);
        long bytesRead = multipartRequest.getBytesRead();
        // 处理文件上传请求
        // ...
    

    这样就可以在控制器中获取文件上传的进度了。

    需要注意的是,文件上传进度的计算是基于 HTTP 请求的字节流的读取,因此只有在客户端上传数据时才能获得上传进度,如果客户端上传过程中中断了上传,那么上传进度也会中断。

  •