【问题标题】:File upload progress bar using RestTemplate.postForLocation使用 RestTemplate.postForLocation 的文件上传进度条
【发布时间】:2012-12-02 17:15:29
【问题描述】:

我有一个将文件上传到 REST 服务的 Java 桌面客户端应用程序。

所有对 REST 服务的调用都使用 Spring RestTemplate 类处理。

我希望实现一个进度条和取消功能,因为正在上传的文件可能非常大。

我一直在寻找一种在网络上实现此功能的方法,但没有成功。

我尝试实现自己的 ResourceHttpMessageConverter 并替换 writeInternal() 方法,但在实际发布请求之前,似乎在某种缓冲操作期间调用了此方法(因此在发送之前一次性读取流) .

我什至尝试过覆盖 CommonsClientHttpRequestFactory.createRequest() 方法并使用特殊的 writeRequest() 方法实现我自己的 RequestEntity 类,但出现了同样的问题(在实际发送帖子之前已读取所有流)。

我找错地方了吗?有没有人做过类似的事情。

我在网上读到的很多关于实现进度条的内容都谈到了停止上传,然后使用单独的 AJAX 请求轮询 Web 服务器的进度,这似乎是一种奇怪的方式。

非常感谢任何帮助或提示。

【问题讨论】:

  • 这可能有你要找的东西stackoverflow.com/questions/5294532/…
  • 感谢您的链接。不幸的是,给出的示例使用了低级 apache 库,所以我不清楚 Spring Rest 库中等效的 FileBody 类是什么,或者我如何注入自己的实现供他们使用。

标签: spring upload progress-bar multipart resttemplate


【解决方案1】:

这是一个老问题,但它仍然是相关的。

我尝试实现自己的 ResourceHttpMessageConverter 并替换 writeInternal() 方法,但在实际发布请求之前,似乎在某种缓冲操作期间调用了此方法(因此在发送之前一次性读取流) .

你在正确的轨道上。此外,您还需要在 RestTemplate 的 HttpRequestFactory 上禁用请求正文缓冲,如下所示:

HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setBufferRequestBody(false);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);

这是working example for tracking file upload progress with RestTemplate.

【讨论】:

  • 感谢您提供此信息,听起来就像我所追求的。 10 年太晚了,但迟到总比没有好?。希望它会对其他人有所帮助?
【解决方案2】:

没有太多关于这个应用是什么,或者它是如何工作的细节,所以这个回复是模糊的,但我相信你可以做这样的事情来跟踪你的上传进度。

如果这确实是一个 Java 客户端应用程序(即不是 HTML/JavaScript,而是一个 Java 程序)并且您确实让它以流的形式上传文件,那么您应该能够通过计算文件中的字节数来跟踪您的上传进度在流缓冲区中传输的数组,并将其与文件对象的总字节数进行比较。

当你得到文件时得到它的大小。

Integer totalFile = file.getTotalSpace();

无论你在哪里作为流传输,你大概是在向某种输出缓冲区添加字节

byte[] bytesFromSomeFileReader =  [whatEverYouAreUsingToReadTheFile];

    ByteArrayOutputStream byteStreamToServer = new ByteArrayOutputStream();
    Integer bytesTransmitted = 0;

    for (byte fileByte : bytesFromSomeFileReader) {
        byteStreamToServer.write(fileByte);
            //
            //  Update your progress bar every killo-byte sent.
            //
        bytesTransmitted++;
        if( (bytesTransmitted % 1000) = 0) {
            someMethodToUpdateProgressBar();
        }
    }

【讨论】:

  • 对不起,但这没有帮助。原则上,这个解决方案是合理的,但正如我在 OP 中所说,流似乎在上传开始之前 被完全读取。所以进度条会飞快到 100%,然后不管上传花了多长时间。
  • ???上传前如何阅读?这是不可能的。如前所述,没有详细说明正在做什么或如何做。您必须提供实际详细信息才能提供更详细的答案。
  • 另外,如果我们在这里谈论客户端,流是如何读取的?应该是客户端写的。
  • 我指的流是本地文件的文件输入流,正在上传到远程服务器。我现在无法提供任何细节,因为这是我两年前参与的一个项目!正如我在 OP 中所说,我认为要上传的内容正在被缓冲,因此在任何网络流量开始之前,流已被完全读/写。所以我无法使用这些流来实现进度条。
猜你喜欢
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
相关资源
最近更新 更多