OpenFeign實(shí)現(xiàn)微服務(wù)間的文件下載方式
項(xiàng)目場(chǎng)景
微服務(wù)通過openfeign獲取文件流
問題描述
微服務(wù)通過openfeign獲取文件流,消費(fèi)端獲取的inputSteam=null,無法獲取到文件流信息
解決方案
file服務(wù)(提供者)
根據(jù)附件id,獲取附件路徑下載
@ApiOperation(value = "附件下載")
@RequestMapping(value = "/file/download/v1", method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public void down(HttpServletResponse response,@CustomJSONBody Object object) {
Map<String, String> map = (Map) object;
String fileId = map.get("fileId");
String[] fileInfos = attachmentService.findById(fileId);
InputStream in = null;
try {
String filePath = fileUploadDir + fileInfos[1];
if (File.separator.equals("/")) {
filePath = filePath.replaceAll("\\\\", File.separator);
} else if (File.separator.equals("\\\\")) {
filePath = filePath.replaceAll("/", File.separator);
}
in = new FileInputStream(filePath);
OutputStream out = response.getOutputStream();
byte buffer[] = new byte[1024];
int length = 0;
while ((length = in.read(buffer)) >= 0){
out.write(buffer,0,length);
}
} catch (Exception e) {
logger.error("附件下載異常", e);
} finally {
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
feign
@RequestMapping(value = "/file/download/v1", method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Response down(@CustomJSONBody Object object);
業(yè)務(wù)服務(wù)(消費(fèi)者)
將附件打包zip文件下載(附全部zip打包相關(guān)代碼,可直接看最后一個(gè)執(zhí)行壓縮的方法)
public void zipExcelExport(DisasterHistoryExportDTO dto, HttpServletResponse response) {
List<String> ids = dto.getList().stream().map(DisasterExpandPO::getFileId).collect(Collectors.toList());
List<AttachmentPO> attachmentPOList = attachmentDao.findAllById(ids);
if (CollectionUtils.isNotEmpty(attachmentPOList)) {
try {
response.reset();
// 設(shè)置response的Header
String exportName = URLEncoder.encode(dto.getFileName() + ".zip", "utf-8");
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" + exportName);
response.setHeader("FileName", exportName);
response.setHeader("Access-Control-Expose-Headers", "FileName");
OutputStream out = response.getOutputStream();
excelsToZip(out, attachmentPOList);
out.close();
} catch (IOException ex) {
throw new BusinessException("導(dǎo)出壓縮包失敗");
}
}
}
/**
* 打壓縮包導(dǎo)出
*/
private void excelsToZip(OutputStream out, List<AttachmentPO> list) throws RuntimeException {
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
compressExcel(zos, list);
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils", e);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
throw new BusinessException("關(guān)閉zip輸出流失敗");
}
}
}
}
/**
* 執(zhí)行壓縮
*/
private void compressExcel(ZipOutputStream zos, List<AttachmentPO> list) {
if (CollectionUtils.isNotEmpty(list)) {
for (AttachmentPO item : list) {
byte[] buf = new byte[BUFFER_SIZE];
Map<String, String> map = new HashMap<>();
map.put("fileId", item.getAttachId());
Response response = attachmentCilent.down(map);
Response.Body body = response.body();
try {
InputStream in = body.asInputStream();
zos.putNextEntry(new ZipEntry(item.getOldName()));
int len;
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
in.close();
} catch (IOException e) {
throw new BusinessException("執(zhí)行壓縮失敗");
}
}
}
}
核心代碼
- 提供者:返回void,HttpServletResponse 寫入
- feign:應(yīng)用提供者接口,返回改為Response(用feign.Response來接收)
- 消費(fèi)者:調(diào)用feign,轉(zhuǎn)為InputStream
Response response = attachmentCilent.down(map); Response.Body body = response.body(); InputStream in = body.asInputStream();
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用Maven打包時(shí)包含資源文件和源碼到j(luò)ar的方法
這篇文章主要介紹了使用Maven打包時(shí)包含資源文件和源碼到j(luò)ar的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
springboot+hutool批量生成二維碼壓縮導(dǎo)出功能
這篇文章主要介紹了springboot+hutool批量生成二維碼壓縮導(dǎo)出功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10
activemq整合springboot使用方法(個(gè)人微信小程序用)
這篇文章主要介紹了activemq整合springboot使用(個(gè)人微信小程序用),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
使用Spring的ApplicationEvent實(shí)現(xiàn)本地事件驅(qū)動(dòng)的實(shí)現(xiàn)方法
本文介紹了如何使用Spring的ApplicationEvent實(shí)現(xiàn)本地事件驅(qū)動(dòng),通過自定義事件和監(jiān)聽器,實(shí)現(xiàn)模塊之間的松耦合,提升代碼的可維護(hù)性和擴(kuò)展性。同時(shí)還介紹了異步事件和事件傳遞的相關(guān)知識(shí)2023-04-04
使用MyEclipse 開發(fā)struts2框架實(shí)現(xiàn)登錄功能(結(jié)構(gòu)教程)
這篇文章主要介紹了使用MyEclipse 開發(fā)struts2框架實(shí)現(xiàn)登錄功能(結(jié)構(gòu)教程)的相關(guān)資料,需要的朋友可以參考下2016-03-03
logback和log4j日志框架堆棧信息添加TraceId方式
這篇文章主要介紹了logback和log4j日志框架堆棧信息添加TraceId方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09

