整个流程有非常多的坑, 前后查阅了十几篇博客, 记录一下方便以后的小伙伴
直接上代码, 已添加注释:
@Value("${it-params.host}")
private String host;
@Value("${it-params.port}")
private String port;
@Value("${ftp.serverIP}")
private String serverIP;
@Value("${ftp.remotePath}")
private String remotePath;
@Override
public void ftpDownload(HttpServletResponse response, String softwareName, String empNo) throws UnsupportedEncodingException {
response.reset();
// 参考 常见的MIME类型表
response.setContentType("application/x-msdownload;charset=UTF-8");
// 文件名转码(防止浏览器显示中文名错误)
String encodeFileName = URLEncoder.encode(softwareName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + encodeFileName);
// 创建FTPClient对象
FTPClient ftp = new FTPClient();
try (OutputStream out = response.getOutputStream()) {
int reply;
// 连接前设置字符编码
ftp.setCharset(StandardCharsets.UTF_8);
ftp.setControlEncoding("UTF-8");
// 连接FTP服务器
// 如果采用默认端口,可以使用ftp.connect(ip)的方式直接连接FTP服务器
ftp.connect(serverIP);
// 不需要账号密码时匿名登录
ftp.login("anonymous", null);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return;
}
// 设置文件类型为二进制 (必须, 否则文件无法打开, 血的教训)
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// 转到指定下载目录
ftp.changeWorkingDirectory(remotePath);
// 列出该目录下所有文件
FTPFile[] fs = ftp.listFiles();
// 遍历所有文件,找到指定的文件
for (int i = 0; i < fs.length; i++) {
FTPFile ff = fs[i];
if (ff.getName().equals(softwareName)) {
ftp.retrieveFile(ff.getName(), out);
out.flush();// 将缓冲区中的数据全部写出
break;
}
}
// 退出ftp
ftp.logout();
LOGGER.info("从FTP服务器下载文件成功!");
// 下载完成后调用it服务记录下载历史(业务相关, 可删除)
String url = "http://" + host + ":" + port + "/softwareList/saveDownloadHistory";
DownloadHistoryDto dto = new DownloadHistoryDto().setEmpNo(empNo).setSoftwareName(softwareName);
String body = HttpRequest.post(url).body(JSONUtil.toJsonStr(dto)).execute().body();
LOGGER.warn("request saveDownloadHistory: {}", body);
} catch (IOException e) {
LOGGER.error("从FTP服务器下载文件失败: {}", e.getMessage());
e.printStackTrace();
} finally {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
LOGGER.info(ioe.getMessage());
}
}
}
}
依赖:
<!--ftp下载-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.7</version>
</dependency>
使用Get请求在浏览器直接调用该接口即可测试.
