背景
服务 consumer 需要通过feign调用 provider 的下载接口。
provider 的下载内容是放在了 HttpServletResponse 中的,接口返回的是 void。
代码如下:
// provider
@GetMapping("download")
public void download(@RequestParam("ids") List<String> ids, HttpServletResponse httpResponse){
service.download(ids, httpResponse);
}
一般的思路是让这个接口返回 byte[] ,但我希望直接调用这个接口获取二进制流,不希望改造接口。
解决方法
利用 feign.Response类型接收原始响应数据:
Response
类型:这是 Feign 提供的一种特殊类型,用于处理原始的 HTTP 响应。使用 Response
类型可以避免 Feign 尝试解析响应体。
feign client 代码:
@GetMapping("download")
Response download(@RequestParam("ids") List<String> ids);
consumer 调用:
// 获取原始的 response
Response response = feignClient.download(ids);
// 获取流
try (InputStream inputStream = response.body().asInputStream();
ServletOutputStream outputStream = httpResponse.getOutputStream()) {
// 设置响应头
httpResponse.setContentType("application/zip");
httpResponse.setHeader("Content-Disposition", "attachment; filename=doc.zip");
// 将响应流写入到 ServletOutputStream 中
byte[] buffer = new byte[10240];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
log.error(e);
throw new CobraException(BaseResultCode.FAIL, "doc下载失败");
} finally {
// 关闭 Feign 的响应
response.close();
}