Tom*_*Tom 15 java resttemplate
我有一个客户端需要将大量的大型json文件POST到服务器.我已经能够通过将每个文件读入内存并使用RestTemplate发布整个文件来实现它.但是,客户端快速耗尽处理大型json文件的内存.我想切换到流式方法,但无法弄清楚如何正确使用RestInmplate的FileInputStream.我发现了这个问题,并使用了接受的答案中给出的代码,但我仍然看到内存使用和OutOfMemory异常使我相信它不是流式传输文件,但仍然完全将它们读入内存.我究竟做错了什么?这是我目前的情况:
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);
Run Code Online (Sandbox Code Playgroud)
Sot*_*lis 11
别.使用Resource结合适当的RestTemplate#exchange方法.
HttpEntity用Resourceas 创建一个body.有ClassPathResource代表类路径资源.在RestTemplate默认情况下,注册一个ResourceHttpMessageConverter哪些流.
除了@sotirios-delimanolis 答案之外,您还需要为您指定此设置,RestTemplate以便在内部org.springframework.http.HttpOutputMessage识别您,org.springframework.http.StreamingHttpOutputMessage否则它只会将整个流复制到其内部流,因此您只需将其加载到内存中。通过这种方式,它使用原始流的块并发送它们。
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
Run Code Online (Sandbox Code Playgroud)
我这么说是因为只有一个实现StreamingHttpOutputMessage并且HttpComponentsClientHttpRequestFactory是它被创建的唯一地方。
可重现的例子:
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));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7945 次 |
| 最近记录: |