尝试使用Spring RestTemplate消耗巨大的JSON数据导致java堆空间异常

时间:2016-05-03 19:56:41

标签: java json spring jackson resttemplate

我正在使用Resttemplate从外部服务器中使用巨大的json。当数据集不是很大时,我的代码工作正常但是一旦我针对完整数据集运行它,我就无法将响应映射到bean类。以下是我的代码。

  

public void createCustomCsv(String name, String password, String serverUrl1, String serverUrl2, String propLocation)
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);

RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(requestFactory);

HttpHeaders httpHeaders = customHeaders.createCustomHeaders(name, password);

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
 //Add the required converters
messageConverters.add(new MappingJackson2HttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
 //Add the message converters to the restTemplate
restTemplate.setMessageConverters(messageConverters); 

ResponseEntity<MyDataBean> responseEntity1;
ResponseEntity<MyDataBean> responseEntity2;
try {
    long startTime = System.currentTimeMillis();
    jLog.debug("Start mapping to Pojo :: " +startTime);
    responseEntity1 = restTemplate.exchange(serverUrl1, HttpMethod.GET, httpEntity, MyDataBean.class);
 responseEntity2 = restTemplate.exchange(serverUrl2, HttpMethod.GET, httpEntity, MyDataBean.class);


MyDataBean sampleDataBeanServer1 = responseEntity1 .getBody();
MyDataBean sampleDataBeanServer2 = responseEntity2 .getBody();


processCustomData(sampleDataBeanServer1 , propLocation);
processCustomData(sampleDataBeanServer2 , propLocation);
} catch (RestClientException e) {

    jLog.debug("Something went wrong with ws call:::" +e);
}
}
  

我已经尝试了几个小时并在SO中搜索试图找出一种方法来将响应数据解析到Pojo类中而不会获得内存异常。我知道这可能是因为整个响应被保留在内存中以将其映射到Pojo。下面的代码是找到内存问题的地方。

 responseEntity1 = restTemplate.exchange(serverUrl1, HttpMethod.GET, httpEntity, MyDataBean.class); 

基于docs,我还将BufferRequestBody设置为false,这样响应就不会被加载到内存中。我不确定为什么行为与文档相比有所不同。

 SimpleClientHttpRequestFactory requestFactory = new  SimpleClientHttpRequestFactory();
 requestFactory.setBufferRequestBody(false);

如果有人耐心和善良地帮助我摆脱这种汤,那将是很棒的!我也对任何第三方图书馆的建议持开放态度。

P.N:当数据集不大时,上面的代码非常有用。为简洁起见,省略了bean类代码。

1 个答案:

答案 0 :(得分:0)

要处理大文件,您必须直接从响应流中读取文件。这link可能有所帮助。然后使用缓冲读取器分批读取下载的文件,并将它们放在您的实体中,然后处理它们。

您将无法在一个批处理中处理它们,因为它不适合内存。