使用 RestTemplate 获取 InputStream

2022-09-01 02:47:53

我正在使用URL类从中读取输入流。有什么方法可以使用 RestTemplate 来实现此目的吗?

InputStream input = new URL(url).openStream();
JsonReader reader = new JsonReader(new InputStreamReader(input, StandardCharsets.UTF_8.displayName())); 

我怎样才能得到而不是使用?InputStreamRestTemplateURL


答案 1

前面的答案没有错,但它们没有深入到我喜欢看到的深度。在某些情况下,处理低级别不仅是可取的,而且是必要的,最常见的例子是将大文件从源(某些Web服务器)流式传输到目标(数据库)。如果您尝试使用 ,那么毫不奇怪,您会受到 .是的,您可以滚动自己的HTTP客户端代码,但您必须处理错误的响应代码,响应转换器等。如果您已经在使用Spring,那么寻找是一个自然的选择。InputStreamByteArrayInputStreamOutOfMemoryErrorRestTemplate

在撰写本文时,有一个 具有 ,如果设置,并且响应类型为 ,则返回 ;否则,它将返回 .很明显,你不是唯一一个要求流媒体支持的人。spring-web:5.0.2.RELEASEResourceHttpMessageConverterboolean supportsReadStreamingInputStreamResourceInputStreamResourceByteArrayResource

但是,存在一个问题:在运行后立即关闭响应。因此,即使您要求 ,并得到了它,它也不好,因为响应流已关闭。我认为这是他们忽略的设计缺陷;它应该依赖于响应类型。所以不幸的是,对于阅读,你必须充分消费回应;如果使用 .,则无法传递它。RestTemplateHttpMessageConverterInputStreamResourceRestTemplate

不过,写作是没有问题的。如果你想流一个,会为你做。在引擎盖下,它用于一次写入 4096 个字节,从 到 。InputStreamResourceHttpMessageConverterorg.springframework.util.StreamUtilsInputStreamOutputStream

某些媒体类型支持所有媒体类型,因此根据您的要求,您可能必须从中删除默认媒体类型,并设置所需的媒体类型,同时注意它们的相对顺序。HttpMessageConverterRestTemplate

最后但并非最不重要的一点是,如果您正在上传大型流,则可以并且应该将其设置为。否则,您知道。在撰写本文时,(JDK 客户端)和(Apache HTTP 客户端)支持此功能,但不支持 。同样,设计监督。ClientHttpRequestFactoryboolean bufferRequestBodyfalseOutOfMemoryErrorSimpleClientHttpRequestFactoryHttpComponentsClientHttpRequestFactoryOkHttp3ClientHttpRequestFactory

编辑:提交票证SPR-16885


答案 2

春天有一个.它转换了斯普林的班级。该类封装了 一个 ,您可以通过 获得。org.springframework.http.converter.ResourceHttpMessageConverterorg.springframework.core.io.ResourceResourceInputStreamsomeResource.getInputStream()

综上所述,您实际上可以通过指定调用的响应类型来获得开箱即用的 via。InputStreamRestTemplateResource.classRestTemplate

下面是使用 其中一种方法的示例:RestTemplateexchange(..)

import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.core.io.Resource;

ResponseEntity<Resource> responseEntity = restTemplate.exchange( someUrlString, HttpMethod.GET, someHttpEntity, Resource.class );

InputStream responseInputStream;
try {
    responseInputStream = responseEntity.getBody().getInputStream();
}
catch (IOException e) {
    throw new RuntimeException(e);
}

// use responseInputStream

推荐