项目场景:

微服务通过openfeign获取文件流

问题描述:

微服务通过openfeign获取文件流,消费端获取的inputSteam=null,无法获取到文件流信息


解决方案:

file服务(提供者):根据附件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);

业务服务(消费者):将附件打包zip文件下载(附全部zip打包相关代码,可直接看最后一个执行压缩的方法)

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();
                // 设置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("导出压缩包失败");
            }
        }
    }     
    /**
     * 打压缩包导出
     */
    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("关闭zip输出流失败");
                }
            }
        }
    }
     /**
     * 执行压缩
     */
    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("执行压缩失败");
                }
            }
        }
    }

核心代码:

提供者:返回void,HttpServletResponse 写入
feign:应用提供者接口,返回改为Response(用feign.Response来接收)
消费者:调用feign,转为InputStream

Response response = attachmentCilent.down(map);
Response.Body body = response.body();
InputStream in = body.asInputStream();

参考:
https://www.jianshu.com/p/eeca093741ef?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐