首页 > 解决方案 > 如何有效地从rest api下载文件并将其发送到像RabbitMq这样的消息代理?

问题描述

目标是从 URI 下载文件并将其映射到现有数据模型。此数据模型调用FileNode并具有类型属性InputStream(这InputStream表示文件数据)。我不知道该怎么做。我尝试使用 Spring RestTemplate,但它关闭了InputStreamdoExecute方法中的响应(所有RestTemplate模板方法最终都委托给此方法)。然后我尝试扩展 RestTemplate 并注释关闭 Response InputStream 的代码:

  @Override
  protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor) throws RestClientException {
    Assert.notNull(url, "URI is required");
    Assert.notNull(method, "HttpMethod is required");
    ClientHttpResponse response = null;
    try {
      ClientHttpRequest request = createRequest(url, method);
      if (requestCallback != null) {
        requestCallback.doWithRequest(request);
      }
      response = request.execute();
      handleResponse(url, method, response);
      return (responseExtractor != null ? responseExtractor.extractData(response) : null);
    }
    catch (IOException ex) {
      String resource = url.toString();
      String query = url.getRawQuery();
      resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
      throw new ResourceAccessException("I/O error on " + method.name() +
        " request for \"" + resource + "\": " + ex.getMessage(), ex);
    }
    finally {
      /**** when to close the response? can I use a proxy for the response's InputStream that closes this response when itself is closed?****/
      if(!(responseExtractor instanceof CloseableResponseExtractor)) //?!
      if (response != null) {
        response.close();
      }
    }
  }

然后我认为这应该是一种更简单的方法,所以我发布了这个问题。

注意:我立即将文件发送到消息代理,我的意思是我不必将其保存在内存中。而且我认为将文件保存在内存或磁盘中然后从那里流式传输不是一个好主意,因为文件大小可能太大,我不知道!事实上,我的代码必须是基础设施(遗留代码 + 消息代理 +...)和其余 API 之间的一个非常薄的层,我认为如果我首先将其写入磁盘会严重影响响应时间(我需要编写并从磁盘读取!)。你有什么建议?

这种情况的最佳实践是什么,通常是如何做到的?

谢谢你!

标签: javaspringrest

解决方案


推荐阅读