如何使用 RestTemplate 转发大文件?

2022-09-01 02:22:19

我有一个 Web 服务调用,通过该调用可以上传 zip 文件。然后将文件转发到另一个服务进行存储,解压缩等。现在,文件存储在文件系统上,然后构建文件系统资源。

Resource zipFile = new FileSystemResource(tempFile.getAbsolutePath());

我可以使用ByteStreamResource来节省时间(转发之前不需要将文件保存在磁盘上),但为此我需要构建一个字节数组。如果文件很大,我会得到一个“OutOfMemory:java堆空间”错误。

ByteArrayResource r = new ByteArrayResource(inputStream.getBytes());

使用 RestTemplate 转发文件而不出现 OutOfMemory 错误的任何解决方案?


答案 1

编辑:其他答案更好(使用)https://stackoverflow.com/a/36226006/116509Resource

我原来的答案是:

可用于这种低级操作。在这个片段中,我使用了Commons IO的方法复制输入流。您需要针对您期望的响应类型自定义 。executecopyHttpMessageConverterExtractor

final InputStream fis = new FileInputStream(new File("c:\\autoexec.bat")); // or whatever
final RequestCallback requestCallback = new RequestCallback() {
     @Override
    public void doWithRequest(final ClientHttpRequest request) throws IOException {
        request.getHeaders().add("Content-type", "application/octet-stream");
        IOUtils.copy(fis, request.getBody());
     }
};
final RestTemplate restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);     
restTemplate.setRequestFactory(requestFactory);     
final HttpMessageConverterExtractor<String> responseExtractor =
    new HttpMessageConverterExtractor<String>(String.class, restTemplate.getMessageConverters());
restTemplate.execute("http://localhost:4000", HttpMethod.POST, requestCallback, responseExtractor);

(感谢Baz指出你需要打电话,否则会打败这一点)setBufferRequestBody(false)


答案 2

@artbristol的答案中,你真正需要的唯一部分是这个(你可以把它设置为一个Spring bean):RestTemplate

final RestTemplate restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);     
restTemplate.setRequestFactory(requestFactory);     

在那之后,我认为只是使用a作为你的请求正文会做正确的事情。FileSystemResource

我也成功地使用了这种方式,适用于您已经将数据作为a并且不需要多次使用它的情况。InputStreamResourceInputStream

在我的情况下,我们已经压缩了我们的文件,并将a包装在.GZipInputStreamInputStreamResource


推荐