public class LogInSftpByPubKey {
private static final Logger logger=LoggerFactory.getLogger(AuthSftpByPubKey.class);
/**session 超时时间 1分钟**/
private static final int SESSION_TIME_OUT=60000;//60s
/**
*
* 方法说明:上传本地文件至SFTP服务器指定目录<br>
*
* @param privKeyPath 本地私钥文件绝对路径 eg:../../id_rsa
* @param remoteUser 目标SFTP服务器用户
* @param port 目标主机地址
* @param host 目标端口
* @return ChannelSftp
* @throws Exception Exception
*/
public static ChannelSftp getChannel(String privKeyPath,String remoteUser,int port,String host) throws ServiceException{
JSch jsch = new JSch();
//密钥文件绝对路径
Channel channel=null;
try {
jsch.addIdentity(privKeyPath);
//用户名
Session session = jsch.getSession(remoteUser, host, port);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setTimeout(SESSION_TIME_OUT);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
} catch (JSchException e) {
throw new ServiceException(ExceptionCode.OTHER_EXCEPTION,String.format("获取sftp连接异常:%s", e.toString()));
}
return (ChannelSftp)channel;
}
/**
*
* 方法说明:上传文件到远程SFTP服务器上<br>
*
* @param sftp sftp
* @param remoteUploadDir 远程上传目录 eg: ~/upload/
* @param fileAbsPath 要上传的文件本地绝对路径 eg: /weblogic/test.txt
* @throws ServiceException ServiceException
*/
public static void upload(ChannelSftp sftp,String remoteUploadDir,String fileAbsPath) throws ServiceException{
//check param
if(StringUtils.isEmpty(fileAbsPath)||StringUtils.isEmpty(remoteUploadDir)){
throw new ServiceException(ExceptionCode.ILLEGAL_ARGUMENT, "上传文件绝对路径或远程目录不能为空");
}
File uploadFile=new File(fileAbsPath);
if(!uploadFile.isFile()){
throw new ServiceException(ExceptionCode.OTHER_EXCEPTION, String.format("文件路径:[%s]不是一个文件", fileAbsPath));
}
//upload
try {
sftp.cd(remoteUploadDir);
sftp.put(new FileInputStream(uploadFile), uploadFile.getName());
} catch (Exception e) {
throw new ServiceException(ExceptionCode.OTHER_EXCEPTION, String.format("上传文件至SFTP服务器异常:%s",e.toString()));
}
}
/**
*
* 方法说明:从SFTP服务器上指定目录下载指定文件到本地目录<br>
*
* @param sftp sftp
* @param localPath 本地路径 eg:/weblogic/test/
* @param remoteAbsPath 远程要下载的文件绝对路径 eg:.../.../test.txt
* @param localFileName 本地文件名
* @throws ServiceException ServiceException
*/
public static void download(ChannelSftp sftp,String localPath,String remoteAbsPath,String localFileName) throws ServiceException{
//check param
if (StringUtils.isEmpty(localPath)
|| StringUtils.isEmpty(remoteAbsPath)
|| StringUtils.isEmpty(localFileName)) {
throw new ServiceException(ExceptionCode.ILLEGAL_ARGUMENT, "必须参数不能为空");
}
File localDir=new File(localPath);
if(!localDir.isDirectory()){
throw new ServiceException(ExceptionCode.OTHER_EXCEPTION,String.format("路径:[%s]不是一个目录", localPath));
}
try {
@SuppressWarnings("unchecked")
Vector<LsEntry> vector=(Vector<LsEntry>)sftp.ls(remoteAbsPath);
if(vector==null||vector.size()!=1){
//target file not exist!
throw new ServiceException(ExceptionCode.OTHER_EXCEPTION,String.format("要下载的文件:[%s]不存在SFTP服务器上", localFileName));
}
//删除本地重名文件
String fullFilePath=localPath.endsWith(File.separator)?localPath:(localPath+File.separator)+localFileName;
File oldFile=new File(fullFilePath);
if(oldFile.exists()){
oldFile.delete();
}
sftp.get(remoteAbsPath, fullFilePath);
} catch (SftpException e) {
throw new ServiceException(ExceptionCode.OTHER_EXCEPTION, String.format("从SFTP服务器上下载文件异常:%s", e.toString()));
}
}
public static void closeSession(ChannelSftp sftp){
if(sftp!=null){
try {
sftp.getSession().disconnect();
} catch (JSchException e) {
logger.error("关闭SFTP session 异常",e);
}
}
}