【发布时间】:2018-01-11 16:34:45
【问题描述】:
我需要在 java 中创建一个 rest 服务,它会连接到另一个 rest 服务以进行文件下载。目前,我只需要将文件从另一个后端传输到客户端,但将来会进行一些处理/转换。
对于我项目中的所有 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();
}
注意:上面的代码不起作用,因为下载的附件是损坏的文件
【问题讨论】:
-
RestTemplate 默认会将所有文件作为 byte[] 复制到内存中。 为避免 OutOfMemory 异常,您应该使用流 - 因此您的客户端使用响应中的 InputStream 并将其写入
httpResponse.getOutputStream()。 Here你可以找到一个巧妙的解决方案。 -
您找到解决方案了吗?如果是这样,请告诉我。我也有类似的情况。
-
如果有人在寻找解决方案,请点击此处:stackoverflow.com/questions/47277640/…
标签: java file proxy resttemplate spring-rest