POST InputStream with RestTemplate
Don't. Use a Resource
in combination with an appropriate RestTemplate#exchange
method.
Create an HttpEntity
with the Resource
as the body
. There's ClassPathResource
to represent class path resources. The RestTemplate
, by default, registers a ResourceHttpMessageConverter
.
Internally, the ResourceHttpMessageConverter
streams the request content to the opposite end of the connection with StreamUtils#copy(InputStream, OutputStream)
with a buffer size that's currently set to 4096.
In addition to the @sotirios-delimanolis answer you also need to specify this setting to your RestTemplate
so that internally your org.springframework.http.HttpOutputMessage
is recognized as org.springframework.http.StreamingHttpOutputMessage
because otherwise it just copies the entire stream to its internal stream so you just load it into memory. This way it uses chunks of your original stream and sends them.
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
I say that because there is only one implementation of StreamingHttpOutputMessage
and HttpComponentsClientHttpRequestFactory
is the only place where it is created.
Reproducible example:
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
UrlResource urlResource = new UrlResource(MY_EXTERNAL_FILE_URL) { //uses URL#inputStream
@Override
public String getFilename() {
return FILE_NAME;
}
};
bodyMap.add("file", urlResource); //other service uses -- @RequestParam("file") MultipartFile -- in its controller
RequestEntity<MultiValueMap<String, Object>> request =
RequestEntity.post(URI.create("http://localhost:6666/api/file"))
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(bodyMap);
//should be a @Bean
RestTemplate restTemplate = new RestTemplate ();
HttpComponentsClientHttpRequestFactory requestFactory = new
HttpComponentsClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
System.out.println(restTemplate.exchange(request, FileMetadata.class));