我需要在java中创建一个休息服务,然后连接到另一个休息服务以进行文件下载。现在,我只需要将文件从另一个后端传输到客户端,但将来会进行一些处理/转换。
对于我项目中的所有Web服务,我们使用spring rest(提供和使用服务)。
我的问题是,考虑到文件很大并且我不想遇到OutOfMemory错误,这样做的恰当方法是什么。
其他一些帖子中的人建议在两端使用流,但这真的可能吗?为此,我是否需要先将文件写入磁盘?
我目前的文件下载代码(消费者) -
public BackendResponse<byte[]> callBackendForFile(BackendRequest request) {
String body = null;
ResponseEntity<byte[]> responseEntity = null;
URI uri = createURI(request);
MultiValueMap<String, String> requestHeaders = getHeadersInfo(request.getHttpRequest());
if (HttpMethod.GET.equals(request.getMethod())) {
responseEntity = restTemplate.exchange(uri, request.getMethod(),
new HttpEntity<String>(body, requestHeaders), byte[].class);
} else {
LOG.error("Method:{} not supported yet", request.getMethod());
}
BackendResponse<byte[]> response = new BackendResponse<>();
response.setResponse(responseEntity);
return response;
}
我的客户代码(提供商):
@RequestMapping(value = "/file", method = RequestMethod.GET, produces = "application/xml")
@ResponseBody
public void downloadFileWithoutSpring(HttpMethod method, HttpServletRequest httpRequest,
HttpServletResponse httpResponse) {
BackendRequest request = new BackendRequest(method,
httpRequest.getRequestURI(), httpRequest.getQueryString(), httpRequest);
BackendResponse<byte[]> backendResponse = dutyplanService.getFile(request);
ResponseEntity<byte[]> response = backendResponse.getResponse();
httpResponse.addHeader("Content-Disposition", "attachment; filename=\"" + "attachment.zip" + "\"");
httpResponse.getOutputStream().write(response.getBody());
httpResponse.flushBuffer();
}
注意:由于下载的附件是损坏的文件,上面的代码无法正常工作
答案 0 :(得分:0)
我认为您不需要在服务器上创建该文件,只要您从另一台服务器接收到它的bytearray内容。
您可以尝试将生成注释的值更改为值application/zip
(或application/octet-stream
,具体取决于目标浏览器),而不是“application/xml
”
答案 1 :(得分:0)
您可以直接在restTemplate中传递HttpServletResponse#getOutputStream()
并将其写入而无需在服务器中保存文件。
public void getFile(HttpServletResponse response) throws IOException {
restTemplate.execute(
"http://ip:port/temp.csv",
HttpMethod.GET,
null,
clientHttpResponse -> {
StreamUtils.copy(clientHttpResponse.getBody(), response.getOutputStream());
return null;
}
);
}
请注意,在调用getFile()
之后,您应该像这样关闭outputStream
response.getOutputStream().close()