栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java FTPSClient 上传下载带证书的ftps服务器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java FTPSClient 上传下载带证书的ftps服务器

网上一大把,测试不能用,谷歌了一下,发现少配置了一个环境变量。

System.setProperty("jdk.tls.useExtendedMasterSecret", "false");//设置环境变量

1、版本
		
			commons-net
			commons-net
			3.6
		
2、重写FTPSClient

ftps的require_ssl_reuse配置为YES,所有SSL数据连接都需要显示SSL会话重用,需要重写FTPSClient。

package ftps;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Locale;

import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;

import org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.Util;


public class SSLSessionReuseFTPSClient extends FTPSClient {

	
	@Override
	protected boolean _retrieveFile(String command, String remote, OutputStream local) throws IOException {
		Socket socket = _openDataConnection_(command, remote);
		if (socket == null) {
			return false;
		}
		final InputStream input;
		input = new BufferedInputStream(socket.getInputStream());
		// Treat everything else as binary for now
		try {
			Util.copyStream(input, local, getBufferSize(), CopyStreamEvent.UNKNOWN_STREAM_SIZE, null, false);
		} finally {
			Util.closeQuietly(input);
			Util.closeQuietly(socket);
		}
		// Get the transfer response
		boolean ok = completePendingCommand();
		return ok;
	}

	@Override
	protected void _prepareDataSocket_(final Socket socket) throws IOException {
		if (socket instanceof SSLSocket) {
			// Control socket is SSL
			final SSLSession session = ((SSLSocket) _socket_).getSession();
			final SSLSessionContext context = session.getSessionContext();
			// context.setSessionCacheSize(preferences.getInteger("ftp.ssl.session.cache.size"));
			try {
				final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
				sessionHostPortCache.setAccessible(true);
				final Object cache = sessionHostPortCache.get(context);
				final Method method = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
				method.setAccessible(true);
				final String key = String.format("%s:%s", socket.getInetAddress().getHostName(), String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT);
				method.invoke(cache, key, session);
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
				// Not running in expected JRE
				System.out.println("No field sessionHostPortCache in SSLSessionContext");
			} catch (Exception e) {
				// Not running in expected JRE
				e.printStackTrace();
			}
		}
	}
}
3、封装FTPSUtil工具类

            注意ftp服务器是用的主动模式,还是被动模式。
            ftpsClient.enterRemotePassiveMode();// 主动模式,PORT模式。
            ftpsClient.enterLocalPassiveMode();// 被动模式,PASV模式。

package ftps;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;

public class FTPSUtil {

	private SSLSessionReuseFTPSClient ftpsClient = null;

	
	public boolean login(String ip, int port, String username, String password) {
		try {
			System.setProperty("jdk.tls.useExtendedMasterSecret", "false");//设置环境变量
			ftpsClient = new SSLSessionReuseFTPSClient();
			FTPClientConfig config = new FTPClientConfig();
			ftpsClient.configure(config);
			ftpsClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));// 打印调用日志,调试时使用,上线后注释
			ftpsClient.setControlEncoding("utf-8");// 编码设置必须放在connect前不然不起作用
			ftpsClient.connect(ip);
			ftpsClient.login(username, password);
			System.out.println("connecting...ftps服务器:" + ip + ":" + port);
			int reply = ftpsClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftpsClient.disconnect();
				return false;
			}
			// ftpsClient.enterRemotePassiveMode();// 主动模式,PORT模式。通知客户端打开一个数据端口,服务端将连接到这个端口进行数据传输。
			ftpsClient.enterLocalPassiveMode();// 被动模式,PASV模式。通知服务器打开一个数据端口,客户端将连接到这个端口进行数据传输。
			ftpsClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);// 流传输模式
			ftpsClient.setDataTimeout(18000);// 数据连接超时(以毫秒为单位)
			ftpsClient.execPROT("P");// 数据通道保护级别
			ftpsClient.setFileType(FTP.BINARY_FILE_TYPE);
			ftpsClient.setBufferSize(1024);
			System.out.println("连接成功...ftp服务器:" + ip + ":" + port);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	
	public boolean uploadFile(String directory, File file) {
		try {
			createDirectory(directory);
			ftpsClient.storeFile(file.getName(), new FileInputStream(file));
			ftpsClient.logout();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ftpsClient.isConnected()) {
				try {
					ftpsClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	
	public boolean createDirectory(String remote) {
		String directory = remote;
		try {
			if (!remote.endsWith("/")) {
				directory = directory + "/";
			}
			// 如果远程目录不存在,则递归创建远程服务器目录
			if (!directory.equals("/") && !ftpsClient.changeWorkingDirectory(directory)) {
				int start = 0;
				int end = 0;
				if (directory.startsWith("/")) {
					start = 1;
				} else {
					start = 0;
				}
				end = directory.indexOf("/", start);
				String paths = "", path = "";
				while (true) {
					String subDirectory = remote.substring(start, end);
					path = path + "/" + subDirectory;
					// 目录不存在就创建
					if (!ftpsClient.changeWorkingDirectory(subDirectory)) {
						if (ftpsClient.makeDirectory(subDirectory)) {
							ftpsClient.changeWorkingDirectory(subDirectory);
						}
					}
					paths = paths + "/" + subDirectory;
					start = end + 1;
					end = directory.indexOf("/", start);
					// 检查所有目录是否创建完毕
					if (end <= start) {
						break;
					}
				}
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	
	public boolean downloadFile(String directory, File file) {
		FileOutputStream fos = null;
		try {
			// ftpFiles ftpFiles = ftpsClient.listFiles(ftpsClient.printWorkingDirectory());
			// FTPFile[] ftpFiles = ftpsClient.listFiles(directory);
			String[] listNames = ftpsClient.listNames(directory);
			for (String path : listNames) {
				if (path.endsWith(file.getName())) {
					while (!file.getParentFile().exists()) {
						file.getParentFile().mkdirs();
					}
					System.out.println("本地保存路径:" + file.getAbsolutePath());
					fos = new FileOutputStream(file);
					ftpsClient.retrieveFile(path, fos);
					System.out.println("下载文件成功");
					return true;
				}
			}
			ftpsClient.logout();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (ftpsClient.isConnected()) {
				try {
					ftpsClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}

}
4、测试
package ftps;

import java.io.File;

public class Test {

	public static void main(String[] args) {
		String host = "192.168.5.200";
		int port = 21;
		String userName = "bossftps";
		String passWord = "123456";

		FTPSUtil ftps = new FTPSUtil();
		ftps.login(host, port, userName, passWord);

		String directory = "/data/目录1/目录2";
		File file = new File("c:/test/你好.txt");
		ftps.uploadFile(directory, file);

		ftps.login(host, port, userName, passWord);
		directory = "/data/目录1/目录2/你好.txt";
		ftps.downloadFile(directory, file);

	}

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489368.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号