【问题标题】:How to handle file upload chunks on the server (Plupload/Spring MVC)?如何处理服务器上的文件上传块(Plupload/Spring MVC)?
【发布时间】:2023-04-30 02:17:02
【问题描述】:

在我们的客户端上,可以上传大文件。我们想使用分块来减少请求的大小。我们使用Plupload,所以很容易分块发送文件。但是,我不确定如何处理这些块。我们在服务器上使用 Spring MVC,我的控制器方法目前有以下内容:uploadMedia(@RequestBody MultipartFile file) 其中MultipartFileorg.springframework.web.multipart.MultipartFile。这在不进行分块时工作得很好。当我在客户端打开分块时,它仍然可以很好地进入这个方法,但是我在传入的文件中看不到任何标识该块属于哪个文件的文件。希望我只是错过了一些东西。

这似乎是一个常见的工作流程,但我似乎找不到任何关于如何在服务器端完成此操作的好例子。只有 Spring 的解决方案会很棒,但如果需要另一个库,那也很好。我看了一些Apache Commons FileUpload,但我在那里找不到任何关于分块的信息。对此的任何帮助都会很棒。谢谢。

【问题讨论】:

    标签: java spring file-upload plupload chunking


    【解决方案1】:

    我对此进行了更多调试,并在我的控制器方法中添加了一个HttpServletRequest,以查看那里是否有任何可用的东西。我发现我收到的请求是一个org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest,其中有一个名为multipartParameters 的字段,它只是一个HashMap。我发现这张地图有namechunkschunk的键。所以,我决定尝试以下作为我的签名:

    uploadMedia(@RequestBody MultipartFile file, @RequestParam String name, @RequestParam int chunks, @RequestParam int chunk)
    

    果然,这些@RequestParam 参数分别填充了文件名、块数和块号(从零开始)。为每个请求提供此信息将使将块组装到最终文件中变得非常容易。

    还有一点要知道,如果文件不需要分块(文件大小小于块大小),则不会发送chunkschunk 参数。所以,我的最终签名最终看起来像这样:

    uploadMedia(@RequestBody MultipartFile file, @RequestParam String name, @RequestParam(required=false, defaultValue="-1") int chunks, @RequestParam(required=false, defaultValue="-1") int chunk)
    

    然后我可以检查 -1 看看我是否需要担心分块。

    所以,在控制器方法本身我有这样的东西:

    Media media = new Media();
    //set stuff on my Media object for storing info about the file in the DB
    //....
    if (chunks > 0 && chunk > 0)
    {
        //Need to append the bytes in this chunk
        mediaRepository.appendBytes(media, file.getBytes());
        if (chunk == chunks - 1)
        {
            //last chunk, upload is done
            onUploadFinished(media);
        }
    }
    else
    {
        //Write out the first set of bytes
        mediaRepository.saveBytes(media, file.getBytes());
        if (chunks <= 0)
        {
            //no chunks were needed, all the bytes have been written out, upload is done
            onUploadFinished(media);
        }
    }
    

    【讨论】:

    • 能看到更多的控制器吗?我正在尝试实现相同的功能,并且正在为控制器的其余部分苦苦挣扎。
    • 我已更新答案以包含更多控制器代码。
    • 如果您不介意可以分享您的 mediaRepository 的一部分吗?
    • 它只是使用 Java 7 (docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html) 中的 java.nio.file.Files 包。因此,上述方法几乎是单行的。 Files.write(getFilePath(media), bytes, StandardOpenOption.CREATE);Files.write(getFilePath(media), bytes, StandardOpenOption.APPEND);
    • 在发送到数据库之前,您是否将内容块写入临时文件?
    最近更新 更多