我试图从服务A下载zip文件,在那里它调用服务B文件。我需要一个解决方案来跨服务流文件例如当我调用服务A文件时,它将调用服务B。从这里它应该流到服务A。从服务A它将流到调用者。
服务之间流式传输的原因是,我不想将文件存储在服务A中。我只想传递给调用者而不存储它。
并且让我知道在服务A中使用哪个选项。比如ByteArrayResource或rest模板响应提取器等。
限制服务B不在我的控制范围内,所以到目前为止,我接受文件作为字节数组
@RestController
public class FileUploadController {
@Autowired
private RestTemplate restTemplate;
// Assume this is from Service A
@PostMapping(value = "/downloadresource",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<?> downloadByteResource() throws IOException{
ByteArrayResource responseObject;
HttpEntity httpEntity = new HttpEntity<>(new LinkedMultiValueMap<>());
responseObject= restTemplate.exchange("http://localhost:8080/test", HttpMethod.POST, httpEntity,
ByteArrayResource.class).getBody();
return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=test.zip")
.body(responseObject);
}
// Assume below from service B. which is not in my control
@PostMapping(value="/test")
public ResponseEntity<byte[]> test() throws IOException {
File f = new File("/Users/dummy/Downloads/test.zip");
byte[] b = Files.readAllBytes(f.toPath());
return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + f.getName())
.body(b);
}
}
我想我有一些解决方案,根据visulaVM使用低内存(可视化堆内存)。
请让我知道是否有其他更好的选择。
@PostMapping(value = "/downloadextract",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<?> downloadExtract(HttpServletResponse response) throws IOException{
HttpEntity httpEntity = new HttpEntity<>(new LinkedMultiValueMap<>());
ResponseExtractor<Object> extractor = restClient -> {
StreamUtils.copy(restClient.getBody(), response.getOutputStream());
return null;
};
RequestCallback callback = req -> {
req.getHeaders().add("auth", "token");
};
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.addHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=test.zip");
restTemplate.execute("http://localhost:8081/test", HttpMethod.POST, callback,
extractor);
return ResponseEntity.ok().build();
}