问题1:springCloud框架,我写的是resource模块,资源下载是file模块。我需要在resource模块中下载文件png和xml文件并按照指定的文件格式压缩为zip文件,压缩完为zip文件,读取这个zip文件流作为一个北向接口。所有的文件下载操作都是在file模块中,所以我的resource模块只是作为一个中间转发命令和读取文件的作用。
解决1:在resource中指定创建两个目录(image和xml),使用fegin调用file模块的下载接口传入创建的两个目录结构,将png下载在image文件夹中,xml文件下载在xml文件夹中。file模块下载完成后通过fegin返回值告诉resource模块下载完成。本地测试完成,此思路可选。
问题2:上述方法中,file和resource模块是部署在同一个服务器上是可取的,如果是部署在容器内,可以把resource的创建目录映射到宿主机上,让file和resource共享一个目录也是可行的,但是如果file和resource是部署在不同机器上那怎么处理!只能抛弃解决1的思路了。
解决2:resource模块只负责发送下载命令,下载文件后压缩文件夹都由file模块来操作。file模块将文件下载后压缩完成,最后读取压缩文件流,将文件流返回给resource模块,resource模块拿到文件流发送给北向接口即可!所以这块就需要用到fegin返回流。
步骤1:file模块暴露一个返回Reponse的接口api
@PostMapping(value="dataSet/dataSetToZipInputStream/feign")
Response dataToZipInputstream(@RequestParam("sysType") Integer sysType, @RequestParam("dataSetId") String dataSetId, @RequestParam("tempFolder1") String tempFolder1, @RequestParam("tempFolder2") String tempFolder2,@RequestParam("zipPath")String zipPath);
步骤2:file模块实现这个api
@PostMapping("dataSetToZipInputStream/feign")
public void dataSetToZipInputStream(HttpServletRequest request, HttpServletResponse response,
@RequestParam("sysType") Integer sysType, @RequestParam("dataSetId") String dataSetId,
@RequestParam("tempFolder1") String tempFolder1, @RequestParam("tempFolder2") String tempFolder2,
@RequestParam("zipPath") String zipPath) {
dataSetService.dataSetToZipInputStream(request, response,sysType, dataSetId, tempFolder1,tempFolder2,zipPath);
}
@Override
public void dataSetToZipInputStream(HttpServletRequest request, HttpServletResponse response,Integer sysType, String dataSetId, String tempFolder1, String tempFolder2,String zipPath) {
String tempFolder3=""; //生成的压缩文件目录
String tempFolder4=""; //压缩文件结构
FileUtil.mkdir(tempFolder1);//image文件夹
FileUtil.mkdir(tempFolder2);//xml文件夹
log.info("创建临时路径1:{}",tempFolder1);
log.info("创建临时路径2:{}",tempFolder2);
BufferedOutputStream bos = null;
InputStream in = null;
try {
……//省去下载文件代码
log.info("下载结束");
tempFolder4 = zipPath +dataSetId + File.separator;
if(EmptyUtil.isNotEmpty(tempFolder3)){
//压缩样本数据
FileOutputStream fos1= null;
try {
tempFolder3 = zipPath + tempFolder3 + ".zip";
fos1 = new FileOutputStream(new File(tempFolder3));
} catch (FileNotFoundException e) {
e.printStackTrace();
log.info("压缩数据集文件失败!");
}
ZipUtils.toZip(tempFolder4, fos1,true);
fos1.flush();
fos1.close();
//开始从压缩文件读流
File fil = new File(tempFolder3);
InputStream zipIn = null;
zipIn = new FileInputStream(fil);
OutputStream outStream;
try {
outStream = response.getOutputStream();
//将压缩文件流放到response返回流中
byte[] bytes = new byte[1024 * 10];
int len = 0;
while ((len = zipIn.read(bytes)) != -1) {
outStream.write(bytes, 0, len);
}
zipIn.close();
outStream.flush();
outStream.close();
} catch (IOException e) {
log.error("exception", e);
}
try {
fos1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("下载失败:", e);
} finally {
if (null != bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//删除临时文件
FileUtil.del(tempFolder1);
FileUtil.del(tempFolder2);
FileUtil.del(tempFolder3);
FileUtil.del(tempFolder4);
}
}
步骤3:response模块继承file模块的api接口,并且调用该方法,获取到返回的文件流
//部分代码片段 此处Response是Fegin包的
Response response = dataSetApi.dataToZipInputstream(resourceUploadSampleDO.getSysType(), resourceUploadSampleDO.getDatasetId(), tempFolder1, tempFolder2,zipPath);
Response.Body body = response.body();
InputStream inputStream = null;
try {
inputStream = body.asInputStream();
//这里的inputStream就是file模块返回的fegin流了,拿到手就可以任意操作
} catch (IOException e) {
log.debug("上传失败!异常信息{}",e.getMessage());
e.printStackTrace();
}



