我再后台进行rest请求excel文件资源下载时,出现了
我们项目用的微服务,我负责界面展示,在后台使用rest请求api来获取文件资源,在进行文件请求时,API调用各个服务在FTP上生成excel文件,然后API再从ftp上下载文件并且通过流的方式返回给我。
第一步排除FTP上文件生成是不是有问题
直接FTP把文件下载到本地,打开文件是没有问题的。那么就可以定位到时项目进行文件传输的时候出现问题。
第二步排查是不是在下载时没有设置response.addHeader("Content-Length", String.valueOf(fis.getChannel().size()));
api的文件下载代码
if(result.getFileName().split("\\.")[1].contains("xls")){
if("xlsx".equals(result.getFileName().split("\\.")[1])){
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}else{
response.setContentType("application/vnd.ms-excel;charset=utf-8");
}
response.setHeader("Content-Disposition", "attachment;filename=\"" + java.net.URLEncoder.encode(result.getFileName(), "UTF-8") + "\"");
response.addHeader("msg", Constants.SUCCESS_MSG);
//打开输出流
OutputStream os = response.getOutputStream();
FileInputStream fis = new FileInputStream(new File(result.getReportAddress()));
response.addHeader("Content-Length", String.valueOf(fis.getChannel().size()));
// 读取文件并输出
byte[] b = new byte[8192];
int i = 0;
while ((i = fis.read(b)) > 0) {
os.write(b, 0, i);
}
// 关闭流
fis.close();
os.flush();
os.close();
添加完response的内容长度之后, 在windows环境通过tomcat启动进行文件下载是没有问题的,但是在linux环境下启动项目下载依旧还是原来的问题,然后我们就把项目转换到了环境编码上
查看linux环境编码,是utf8,所以应该不是环境编码的问题
我们又把矛头抛向了ftp的下载上
第三步ftp文件下载代码
FTPClient ftp = new FTPClient();
logger.info("FTP ip:{},端口:{},用户名:{},文件目录:{},自定义文件目录:{},文件名:{},本地文件路径:{}",host, port, username, remotePath, customPath,
fileName, localPath);
try {
int reply;
ftp.setControlEncoding("utf-8");
ftp.connect(host, port);
// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
ftp.login(username, password);// 登录
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return result;
}
ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
logger.info("转移到FTP服务器目录:"+remotePath);
ftp.changeWorkingDirectory(customPath);// 转移到FTP服务器目录
logger.info("转移到FTP指定目录:"+customPath);
File path = new File(localPath);
if (path.exists()) {
if (path.isDirectory()) {
System.out.println("dir exists");
} else {
System.out.println("the same name file exists, can not create dir");
}
} else {
System.out.println("dir not exists, create it ...");
path.mkdir();
}
File localFile = new File(localPath + "/" + fileName);
OutputStream is = new FileOutputStream(localFile);
ftp.retrieveFile(fileName, is);
is.close();
ftp.logout();
然后看下是不是FTP进行下载时编码的问题
https://www.cnblogs.com/shunxiyuan/p/5413420.html
这篇文章中提到了一些疑惑
然后在ftp下载中添加了
ftp.enterLocalPassiveMode(); //设置被动模式
ftp.setFileType(ftpc.BINARY_FILE_TYPE); //设置下载文件为二进制模式
ftp.setFileTransferMode(ftpc.STREAM_TRANSFER_MODE); ///传输文件为流的形式
这三句话完美解决。