Mat*_*nkt 7 java spring spring-mvc
我正在尝试使用spring将文件下载的结果直接传输到另一个帖子 RestTemplate
我目前的做法如下:
ResponseEntity<InputStreamResource> downloadResponse = restTemplate.getForEntity(fileToDownloadUri, InputStreamResource.class);
InputStreamResource imageInputStreamResource = downloadResponse.getBody();
ResponseEntity<String> response = restTemplate.exchange(storageUri, POST, new HttpEntity<>(imageInputStreamResource), String.class);
Run Code Online (Sandbox Code Playgroud)
但是,运行上面的代码时出现以下异常:
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://host:port/path/some.jpg": stream is closed; nested exception is java.io.IOException: stream is closed
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:6
...
Caused by: java.io.IOException: stream is closed
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3348)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3373)
Run Code Online (Sandbox Code Playgroud)
似乎响应总是作为处理的最后一步关闭.响应时,HttpURLConnection
关闭,流不再可处理.
我希望能够实现这个场景,而不必完全存放文件在内存中或将其写入文件(如描述在这里).
任何提示都非常感谢.
use*_*011 20
如果要直接转发响应而不将其保留在内存中,则必须直接写入响应:
@RequestMapping(value = "/yourEndPoint")
public void processRequest(HttpServletResponse response) {
RestTemplate restTemplate = new RestTemplate();
response.setStatus(HttpStatus.OK.value());
restTemplate.execute(
fileToDownloadUri,
HttpMethod.GET,
(ClientHttpRequest requestCallback) -> {},
responseExtractor -> {
IOUtils.copy(responseExtractor.getBody(), response.getOutputStream());
return null;
});
}
Run Code Online (Sandbox Code Playgroud)
由于您告诉 RestTemplate 期待 InputStreamResource,它会尝试使用适当的转换器将您的消息转换为 InputStreamResource。(我猜没有人可以按照您的意愿处理这个问题)
您应该能够让它期待一个资源,您可以从中获取输入流并读取该资源。
import org.springframework.core.io.Resource;
ResponseEntity<Resource> exchange = RestTemplate.exchange(url, HttpMethod.GET, new HttpEntity(httpHeaders), Resource.class);
InputStream inputStream = exchange.getBody().getInputStream();
Run Code Online (Sandbox Code Playgroud)
使用它您可以将响应写入其他地方。Files.write(inputStream, new File("./test.json"));
为我编写了该文件,所以我认为输入流也可以在其他地方使用。(我用的是Spring 4.3.5)
编辑:
正如OP所述,这仍会将文件加载到内存中。在幕后,InputStream 是一个 ByteArrayInputStream。
默认的 RestTemplate 和 MessageConverters 根本不是为流内容而设计的。您可以编写自己的org.springframework.web.client.ResponseExtractor
MessageConverter 实现。在 ResponseExtractor 中,您可以访问org.springframework.http.client.ClientHttpResponse
恕我直言,对于您的用例,您可能最好使用 Apache Httpcomponents HttpClient ,您可以在其中找到HttpEntity#writeTo(OutputStream)
.
归档时间: |
|
查看次数: |
12737 次 |
最近记录: |