如果文件大,Java会报OOM(out of memory)。使用ResponseExtractor将远程服务器中的文件直接转成流存到文件中,而不放到内存。
事例代码如下:
@GetMapping("/test-download-v3")
public void downloadFile() throws IOException {
String url = "http://img.championat.com/news/big/l/c/ujejn-runi_1439911080563855663.jpg";
// Optional Accept header
RequestCallback requestCallback = request -> request
.getHeaders()
.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
// Streams the response instead of loading it all in memory
ResponseExtractor<Void> responseExtractor = response -> {
// Here you can write the inputstream to a file or any other place
Path path = Paths.get("downloadv3.jpg");
Files.copy(response.getBody(), path);
return null;
};
restTemplate.execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
这里要注意的是,有些厂家提供的下载,刚开始是1MB/s,后面直接是1B/s,简直是坑,对此,要设置下下载时间,比如5分钟没下载好,就不下了。
String url = "http://img.championat.com/news/big/l/c/ujejn-runi_1439911080563855663.jpg";
SimpleClientHttpRequestFactory httpFactory = new SimpleClientHttpRequestFactory();
httpFactory.setReadTimeout(1);
restTemplate.setRequestFactory(httpFactory);
try{
RequestCallback requestCallback = request -> request.getHeaders().setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
ResponseExtractor<Void> responseExtractor = response -> {
Path path = Paths.get("C:\\Users\\cff\\Desktop\\downloadv3.jpg");
Files.copy(response.getBody(), path);
return null;
};
restTemplate.execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
catch (Exception e){
e.printStackTrace();
}
finally {
}
System.out.println("over");
如下:
这里可以在异常里面捕获,然后发送邮件,给客户,说着玩意下不下来。