当前位置: 首页 > 知识库问答 >
问题:

使用RestTemplate获取InputStream

惠诚
2023-03-14

我使用URL类从中读取InputStream。有什么方法可以使用RestTemplate实现这一点吗?

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

如何使用RestTemplate而不是使用URL来获取InputStream?

共有3个答案

沙柏
2023-03-14

您不应该直接获取输入流<代码>RestTemplate旨在封装对响应(和请求)内容的处理。它的优势在于处理所有IO并为您提供一个现成的Java对象。

RestTemboard的原作者之一Brian Clozel曾表示:

restemplate并不意味着流式传输响应体;它的合同不允许这样做,而且它已经存在很长时间了,如果不中断许多应用程序,就无法改变其行为的如此基本的一部分。

您需要注册适当的HttpMessageConverter对象。它们可以通过HttpInputMessage对象访问响应的InputStream。

正如Abdull所建议的那样,Spring确实为资源提供了一个HttpMessageConverter实现,它本身封装了一个输入流,ResourceHttpMessageConverter。它不支持所有的资源类型,但是由于您无论如何都应该对接口进行编程,因此您应该只使用superinterface资源。

当前实现(4.3.5)将返回一个ByteArrayResource,并将响应流的内容复制到您可以访问的新的ByteArrayInputStream。

你不必关闭小溪。RestTemplate为您解决了这个问题。(如果您尝试使用另一种由ResourceHttpMessageConverter支持的类型InputStreamResource,这是很不幸的,因为它包装了底层响应的InputStream,但在向客户端代码公开之前就被关闭了。)

蒋寒
2023-03-14

Spring有一个org.springframework.http.converter.ResourceHttpMessageConverter。它转换Spring的org.springframework.core.io.资源类。该资源类封装了一个InputStream,您可以通过一些esource.getInputStream()获取它。

将所有这些放在一起,您实际上可以通过开箱即用的RestTemboard获得InputStream,方法是将Resource.class指定为您的RestTemboard调用的响应类型。

下面是一个使用RestTemplate的示例 方法:

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
解鸿运
2023-03-14

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

在撰写本文时,spring-web: 5.0.2。RELEASE有一个ResourceHttpMessageConverter,它有一个布尔支持ReadStreaming,如果设置,并且响应类型为InputStreamResources,则返回InputStreamResources;否则它返回ByteArrayResources。很明显,您不是唯一一个要求流媒体支持的人。

但是,存在一个问题:restemplate在HttpMessageConverter运行后不久关闭响应。因此,即使您请求输入流资源(InputStreamResource)并得到了它,这也不好,因为响应流已经关闭。我认为这是他们忽视的一个设计缺陷;它应该取决于响应类型。所以不幸的是,对于阅读,你必须充分利用回应;如果使用RestTemplate,则无法传递它。

不过,编写不是问题。如果您想流式传输InputStreamResourceHttpMessageConverter会为您完成。在幕后,它使用org.springframework.util.StreamUtils一次从InputStreamOutputStream写入4096个字节。

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

最后但并非最不重要的一点是,ClientHttpRequestFactory的实现具有一个布尔缓冲请求体(bufferRequestBody),如果您正在上载大流,则可以并且应该将其设置为false。否则,您知道,OutOfMemoryError。在本文撰写时,SimpleClientHttpRequestFactory(JDK客户端)和HttpComponentsClientHttpRequestFactory(apachehttp客户端)支持此功能,但不支持okhttp3clienthttpprequestfactory。再次强调,设计监督。

编辑:归档机票SPR-16885。

 类似资料:
  • 问题内容: 我正在使用URL类从中读取InputStream。有什么我可以使用RestTemplate的方法吗? 我怎样才能 用,而不是使用? 问题答案: 您不应该直接获得。旨在封装处理响应(和请求)内容。它的优势在于处理所有IO,并为您提供现成的Java对象。 的一位原始作者Brian Clozel 表示: 并不意味着流响应主体;它的合同不允许这样做,而且已经存在了很长时间,以至于在不中断许多应

  • 那么,为什么它要尝试将响应解析为JSON呢?我该如何解决呢? 谢谢!!

  • 我有两个问题: 如何使用spring RestTemplate映射JSON对象列表。 如何映射嵌套的JSON对象。 我正在尝试使用https://bitpay.com/api/rates,方法是按照http://spring.io/guides/gs/consource-rest/的教程学习。

  • 我用的是swapi。在Spring Boot中获取应用程序数据的dev API。我需要用一个行星的名字来获取它的信息。因此,我使用下一个url:https://swapi.dev/api/planets/?search=Tatooine.JSON结果如下所示: 现在,在Java中,我使用服务中的下一个代码: 我只需要得到结果的数组,但是,我如何从对象得到结果的数组?

  • 我试图向Api Rest发出get请求,但我总是得到404,尽管如此,如果尝试在浏览器或邮递员中复制queryUrl,它会非常工作。 我也试过这个: 但什么都没变。有人能帮我吗?

  • 问题内容: 我有两个问题: 如何使用Spring RestTemplate映射JSON对象列表。 如何映射嵌套的JSON对象。 问题答案: 也许这样 控制器代码 RequestMapping 是对扩展名的添加状态代码。使用以及方法。在此类中,由和返回。