为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 REST 模板 Spring MVC 获取大型 JSON 而不会在

如何使用 REST 模板 Spring MVC 获取大型 JSON 而不会在

largeQ 2022-06-04 09:16:43
当我从 REST 服务获取大型 JSON 时,我收到 java.lang.OutOfMemoryError: Java heap space...这发生在 ~1000 次调用 REST 服务之后    HttpEntity<ProductRequest> requestUpdate = new HttpEntity<>(request, httpHeaders);    ResponseEntity<String> messageEntity = restTemplate.exchange(getEndPointAddress(), HttpMethod.POST, requestUpdate, String.class);    Map<String, Object> map = gson.fromJson(Helper.cleanJson(messageEntity.getBody()), Map.class);<pre>java.lang.OutOfMemoryError: Java heap space    at java.util.Arrays.copyOfRange(Arrays.java:2694) ~[?:1.7.0_181]    at java.lang.String.<init>(String.java:203) ~[?:1.7.0_181]    at java.lang.StringBuilder.toString(StringBuilder.java:405) ~[?:1.7.0_181]    at org.springframework.util.StreamUtils.copyToString(StreamUtils.java:80) ~[stormjar.jar:4.0.3]    at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:86) ~[stonjar.jar:4.0.3]    at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:41) ~[stonjar.jar:4.0.3]    at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:193) ~[stonjar.jar:4.0.3]    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:104) ~[stonjar.jar:4.0.3]    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:884) ~[stonjar.jar:4.0.3]    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:868) ~[stonjar.jar:4.0.3]    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:622) ~[stonjar.jar:4.0.3]    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580) ~[stonjar.jar:4.0.3]
查看完整描述

1 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

RestTemplate并且底层的 Spring bean 不是为流处理而设计的,它们ResponsEntity在内存中构建了整个。根据您的示例,您没有RestTemplate按预期使用。您正在阅读 String而不是将响应对象反序列化委托Map<String, Object>给底层转换器 bean。


如果 JSON 响应真的太大而无法放入您的堆中,您可以替换RestTemplate为URLConnection或任何其他可以让您InputStream直接访问响应的 HTTP 客户端库。这将允许您手动读取和解析响应,例如使用com.google.gson.stream.JsonReader:


URLConnection conn = // create and open

JsonReader reader = new JsonReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

// read manually using reader

String通过避免包含整个 JSON 主体的一个大对象,您将能够以这种方式节省内存。


查看完整回答
反对 回复 2022-06-04
  • 1 回答
  • 0 关注
  • 110 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信