Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用RestTemplate发布InputStream_Java_Resttemplate - Fatal编程技术网

Java 使用RestTemplate发布InputStream

Java 使用RestTemplate发布InputStream,java,resttemplate,Java,Resttemplate,我有一个客户端,需要将大量大型json文件发布到服务器。通过将每个文件读入内存并使用RestTemplate发布整个文件,我已经能够让它正常工作。但是,客户机在处理大型json文件时很快就会耗尽内存。我想切换到流方法,但不知道如何正确地将FileInputStream与RestTemplate一起使用。我找到并使用了公认答案中给出的代码,但我仍然看到内存使用和OutOfMemory异常,这使我相信它不是流式传输文件,而是将它们完全读入内存。我做错了什么?以下是我目前的情况: final Inpu

我有一个客户端,需要将大量大型json文件发布到服务器。通过将每个文件读入内存并使用RestTemplate发布整个文件,我已经能够让它正常工作。但是,客户机在处理大型json文件时很快就会耗尽内存。我想切换到流方法,但不知道如何正确地将FileInputStream与RestTemplate一起使用。我找到并使用了公认答案中给出的代码,但我仍然看到内存使用和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);
final InputStream fis=ApplicationStore.class.getResourceAsStream(路径);
final RequestCallback RequestCallback=new RequestCallback(){
@凌驾
public void doWithRequest(最终ClientHttpRequest请求)引发IOException{
request.getHeaders().add(“内容类型”、“应用程序/json”);
copy(fis,request.getBody());
}
};
最终RestTemplate RestTemplate=新RestTemplate();
SimpleClientHttpRequestFactory requestFactory=新的SimpleClientHttpRequestFactory();
requestFactory.setBufferreRequestBody(false);
setRequestFactory(requestFactory);
最终HttpMessageConverterExtractor响应Extractor=
新的HttpMessageConverterExtractor(String.class,restTemplate.getMessageConverters());
restemplate.execute(“http://“+host+”:8080/upads数据结构“+”/ruleset”、httpMethod、requestCallback、responseExtractor);
不要这样做。结合适当的方法使用

创建一个
HttpEntity
,将
资源作为
主体
。有两种方法来表示类路径资源。默认情况下,
RestTemplate
注册一个
ResourceHttpMessageConverter


内部,,
ResourceHttpMessageConverter
将请求内容流式传输到当前设置为4096的连接的另一端。

除了@sotirios delimanolis应答之外,您还需要将此设置指定到
RestTemplate
,以便
org.springframework.http.HttpOutputMessage
被识别为
org.springframework.http.streaminghttpoutmessage
,因为否则它只会将整个流复制到其内部流,所以您只需将其加载到内存中。通过这种方式,它使用原始流的块并发送它们

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplate.setRequestFactory(requestFactory);
我这么说是因为只有一个
streaminghttpoutmessage的实现
,而
httpcomponents客户端httprequestfactory
是创建它的唯一地方

可复制示例:

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));
MultiValueMap bodyMap=新链接的MultiValueMap();
URLROURCE URLROURCE=新的URLROURCE(我的外部文件){//使用URL#inputStream
@凌驾
公共字符串getFilename(){
返回文件名;
}
};
bodyMap.add(“文件”,urlResource)//其他服务在其控制器中使用--@RequestParam(“file”)MultipartFile
请求实体请求=
RequestEntity.post(URI.create(“http://localhost:6666/api/file"))
.contentType(MediaType.MULTIPART\u表单\u数据)
.车身(车身图);
//应该是@Bean
RestTemplate RestTemplate=新的RestTemplate();
HttpComponents客户端HttpRequestFactory请求工厂=新建
HttpComponents客户端HttpRequestFactory();
requestFactory.setBufferreRequestBody(false);
setRequestFactory(requestFactory);
System.out.println(restemplate.exchange(request,FileMetadata.class));

谢谢。HttpComponents客户端HttpRequestFactory在添加到时似乎正是我所需要的。