ftp工具类 FtpUtil 中部分代码如下:
import org.apache.commons.net.ftp.*;
public class FtpUtil {
private static Logger log = Logger.getLogger(FtpUtil.class);
private FTPClient ftpClient;
private FtpUtil(){}
/**
* @description 创建ftp连接实例
*/
public static FtpUtil getInstance(String serverUrl, String port, String userName, String password) throws Exception{
FtpUtil ftpUtil = new FtpUtil();
ftpUtil.connectServer(serverUrl, port, userName, password);
return ftpUtil;
}
/**
* @description 创建连接
*/
public void connectServer(String serverUrl, String port, String userName, String password) throws Exception {
ftpClient = new FTPClient();
log.debug("连接到ftp服务器:" + serverUrl);
ftpClient.connect(serverUrl, Integer.parseInt(port));
int reply = ftpClient.getReplyCode();
log.debug("响应串为:" + ftpClient.getReplyString());
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
log.info("连接ftp服务器失败");
throw new Exception("连接ftp服务器失败");
} else {
ftpClient.login(userName, password);
log.debug("当前工作目录为:" + ftpClient.printWorkingDirectory());
log.debug("登录ftp服务器成功");
}
}
/**
* 判断文件是否存在
*/
public Boolean isExistFileName(String pathFileName) throws ParseException {
Boolean isExist=false;
// 获得指定目录下所有文件名
FTPFile[] ftpFiles = null;
try {
ftpFiles = ftpClient.listFiles(pathFileName);
} catch (IOException e) {
log.info("获取指定目录:"+pathFileName+"指定文件列表出现异常");
e.printStackTrace();
}
if(ftpFiles!=null&&ftpFiles.length>0){
isExist=true;
}else{
isExist=false;
}
return isExist;
}
}
- Service调用FtpUtil.getInstance方法,可以成功连接ftp服务器,且无异常错误。
- Service调用FtpUtil.isExistFileName方法,提示指定不存在指定文件名的文件,且无异常错误。(经校验,文件存在且目录及文件名都是对的)
【解决】:在程序调用登录方法之前,即执行“FTPClient ftpClient = null; ftpClient.login(username, password);”之前,加上一行代码:ftpClient.enterLocalPassiveMode();这样就可以了。
【分析】:
- 在FTP服务中,涉及到客户端和服务器端的连接,连接就会涉及到端口的打开问题;
- 而端口的打开中,又涉及到主动模式和被动模式。主动模式:客户端开放端口给服务端用;被动模式:服务端开放端口给客户端用。由于很多客户端在防火墙内,开放端口给服务器端用比较困难。所以用被动模式的时候比较多。
- 如果涉及到了内网、局域网等环境时,出现FTP连接问题,也可以考虑是否是因为连接模式引起的。