POST InputStream mit RestTemplate
Ich habe einen client, muss die POST eine große Anzahl von großen json-Dateien auf einem server. Ich habe in der Lage, um es arbeiten, indem Sie Lesen jede der Dateien in den Speicher und die Buchung der gesamten Datei mit RestTemplate. Aber der client läuft schnell aus dem Gedächtnis der Umgang mit den großen json-Dateien. Ich möchte wechseln zu einem streaming-Ansatz, aber können nicht herausfinden, wie Sie ein FileInputStream, der mit der RestTemplate richtig. Ich fand diese Frage und verwendet den code in der akzeptierten Antwort, aber ich bin immer noch zu sehen, die Speichernutzung und die OutOfMemory-Ausnahmen, die dazu führen mich zu glauben, dass es ist nicht ein streaming der Dateien aber immer noch zu Lesen, die Sie in den Speicher komplett. Was mache ich falsch? Hier ist, was ich derzeit habe:
final InputStream fis = ApplicationStore.class.getResourceAsStream(path);
final RequestCallback requestCallback = new RequestCallback() {
@Override
public void doWithRequest(final ClientHttpRequest request) throws IOException {
request.getHeaders().add("Content-type", "application/json");
IOUtils.copy(fis, request.getBody());
}
};
final RestTemplate restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
final HttpMessageConverterExtractor<String> responseExtractor =
new HttpMessageConverterExtractor<String>(String.class, restTemplate.getMessageConverters());
restTemplate.execute("http://" + host + ":8080/upads-data-fabric" + "/ruleset", httpMethod, requestCallback, responseExtractor);
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht. Verwenden Sie eine
Ressourcen
in Kombination mit einer entsprechendenRestTemplate#exchange
Methode.Erstellen Sie eine
HttpEntity
mit derResource
alsbody
. Es gibtClassPathResource
zu vertreten Klassenpfad Ressourcen. DieRestTemplate
standardmäßig registriert einResourceHttpMessageConverter
die streams.ResourceHttpMessageConverter
ist hier. Sie werden feststellen, es nutztStreamUtils#copy
verwendet einen buffer von 4096 bytes.RestTemplate
problem. Das ist entweder ein problem mit TomcatClassLoader
oder Sie haben wirklich keinen Speicher zur Verfügung.Zusätzlich zu den @sotirios-delimanolis Antwort, die Sie auch benötigen, geben Sie diese Einstellung an Ihre
RestTemplate
so, dass intern Ihreorg.springframework.http.HttpOutputMessage
ist anerkannt alsorg.springframework.http.StreamingHttpOutputMessage
weil es sonst nur Kopien der gesamten Strom der interne stream, so dass Sie nur in den Arbeitsspeicher zu laden. Auf diese Weise es verwendet Brocken von Ihrem original-stream und sendet Sie.Ich sage das, weil es nur eine Implementierung von
StreamingHttpOutputMessage
undHttpComponentsClientHttpRequestFactory
ist der einzige Ort, wo es angelegt wird.Reproduzierbare Beispiel: