2016-05-03 6 views
0

Ich benutze Resttemplate, um einen riesigen Json von einem externen Server zu verbrauchen. Mein Code funktioniert einwandfrei, wenn das Dataset nicht groß ist, aber sobald ich es für das vollständige Dataset ausführe, kann ich die Antwort nicht auf die Bean-Klasse zuordnen. Unten ist mein Code.Der Versuch, riesige JSON-Daten mit Spring RestTemplate zu konsumieren, was zu einer Java-Heap-Space-Ausnahme führt

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); 
} 
} 

Ich habe stundenlang versucht, und suchte in SO einen Weg, um herauszufinden, die Antwortdaten in die Pojo Klasse zu analysieren, ohne Speicher zu bekommen Ausnahmen. Ich verstehe, dass dies möglicherweise daran liegt, dass die gesamte Antwort im Speicher gehalten wird, um sie dem Pojo zuzuordnen. Der folgende Code ist, wo das Speicherproblem gefunden wird.

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

Basierend auf docs, ich habe gesetzt auch die BufferRequestBody auf false, so dass die Antwort nicht in den Speicher geladen wird erhalten. Ich bin nicht sicher, warum das Verhalten im Vergleich zu den Dokumenten anders ist.

Es wäre großartig, wenn jemand geduldig und nett ist, um mir aus dieser Suppe zu helfen! Ich bin offen für alle Drittanbieter-Bibliothek Vorschläge.

P.N: Der obige Code funktioniert perfekt, wenn der Datensatz nicht groß ist. Außerdem wurde der Bean-Klassencode der Kürze halber weggelassen.

+0

Sie werden wahrscheinlich Streaming für Ihr JSON-Parsing verwenden müssen. Werfen Sie einen Blick auf die Streaming API von Jackson: http://wiki.fasterxml.com/JacksonStreamingApi. – Chill

+0

Ich habe das schon überprüft. Das Problem bei diesem Ansatz ist, dass ich es nicht an mein Model/Pojos binden könnte. Auch die JSON-Struktur und die Werte, die ich daraus abholen muss, sind ziemlich kompliziert. Daher ist es sehr hilfreich, eine stark typisierte Referenz in Form von Pojos zu verwenden. Ich habe versucht zu denken, ob es eine Möglichkeit gibt, diese Daten in die Pojo-Klasse zu streamen, ohne die gesamte Antwort in den Speicher zu laden. – Sid

+0

Sind Sie sicher, dass Sie in der Lage sein würden, Speicher pojo im Speicher zu haben? Wenn die gestreamten Daten nicht gespeichert werden können, besteht eine gute Chance, dass das Pojo auch nicht passt (da es alle Daten enthält). – Chill

Antwort

0

Um große Dateien verarbeiten zu können, müssten Sie die Datei herunterladen, indem Sie direkt aus dem Antwortstream lesen. Diese link könnte helfen. Und dann lesen Sie aus der heruntergeladenen Datei in Stapeln mit gepufferten Leser und haben sie in Ihren Entitäten und dann verarbeiten sie.

Sie könnten nicht in der Lage sein, sie in einem Stapel zu verarbeiten, da sie nicht in den Speicher passen würden.

+0

Der Server erstellt diese JSON-Daten wie einen Feed. Es ist keine Datei, die ich herunterladen kann, um sie lokal zu bearbeiten. – Sid

+0

Können Sie die Entität in eine Liste von Entitäten aufteilen? Eine einzige Entität mit allen Daten wäre nicht möglich. Google GSON-API ist es wert, nach JSON-Streaming-Streaming zu suchen https://sites.google.com/site/gson/streaming – basiljames

+0

Das Modell basiert auf dem JSON-Format. Es hat bereits mehrere Entitäten, die miteinander verkettet sind.Das Pojo, dem ich versuche zuzuordnen, ist die Wrapper-Modellklasse. Wie bereits erwähnt, besteht das Problem darin, diese riesigen Daten effizient zu verarbeiten oder abzubilden, indem sie nicht vollständig in den Speicher geladen werden. – Sid