【问题标题】:Streaming large files with spring mvc使用 spring mvc 流式传输大文件
【发布时间】:2014-11-03 09:46:01
【问题描述】:

我正在尝试创建一个下载和上传大文件的应用程序,因此我不希望将文件内容存储在内存中。

在 mvc 控制器端,我使用了一个 http 消息转换器,它可以转换为 InputStream 或从 InputStream 转换

@Override
public InputStream read(Class<? extends InputStream> clazz, HttpInputMessage inputMessage) throws IOException,
        HttpMessageNotReadableException {
    return inputMessage.getBody();
}

@Override
public void write(InputStream t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException,
        HttpMessageNotWritableException {

    try {
        IOUtils.copy(t, outputMessage.getBody());
    } finally {
        IOUtils.closeQuietly(t);
    }
}

这在服务器端运行良好。

在客户端 (RestTemplate) 端,我尝试使用相同的转换器,但出现流已关闭的异常(可能在请求完成时关闭)。

客户端代码:

ResponseEntity<InputStream> res = rest.getForEntity(url, InputStream.class);
// res.getBody() is closed

我还尝试将输入流复制到缓冲区并创建一个新的 ByteArrayInputStream 并将其返回给 RestTemplate 客户端,它运行良好,但是它确实需要将数据读入不适合的内存我的要求。

我的问题是如何保持流打开直到我处理它而不必将其全部读入内存/文件?

任何想法都会受到赞赏。

问候,谢伊

【问题讨论】:

  • 你需要输入和输出而不实际保存任何东西,我认为这个页面包含了大多数这样做的方法:stackoverflow.com/questions/43157/…
  • 这个解决方案的问题是在消息转换器中我还不知道如何处理该文件。将其保存到文件中?保存到数据库?等等。只有客户端知道如何处理它。

标签: java spring spring-mvc resttemplate


【解决方案1】:

据我所知,RestTemplate 的 getForEntity() 不是获取 InputStream 的合适方法。这对于在实体类之间进行转换很方便,所以大概这就是您的问题所在。

既然习惯了HttpInputMessage,那为什么不在客户端也使用HttpInputMessage.getBody()呢?它为您提供了一个不错的 InputStream,它可以直接传递给 OutputStream,例如 HttpServletResponse.getOutputStream()。

【讨论】:

  • 转换器本身不知道如何处理文件,只有调用后的代码知道。我可以将它放到一个临时文件中并返回该文件的 FileInputStream,但这效率低下。
  • 当你可以直接在url上获取InputStream的时候,为什么要保存一个文件,然后在保存的文件上获取一个InputStream呢?例如,我使用 Apache Commons 的 HttpMethod.getResponseBodyAsStream() 从 url 获取 InputStream。你肯定有一些方法可以做同样的事情吗?还是我误解了您要做什么?显示更多代码可能是个好主意。
【解决方案2】:

检查 Spring MVC 如何使用 org.springframework.web.multipart.commons.CommonsMultipartResolver 处理大文件上传。它有一个“maxInMemorySize”,可以帮助控制内存需求。请参阅此线程以使用带有 REST 模板 Sending Multipart File as POST parameters with RestTemplate requests 的多部分解析器

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 2011-10-18
    • 2016-01-02
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    相关资源
    最近更新 更多