I am using JSch library for SFTP. I need to do several operations on SFTP server like move remote files in other directory, pull files, etc. For all these operations I need Session
and from it I get Channel
an then cast it to ChannelSftp
. This is redundant step. So I thought of abstracting it into a private
method.
private ChannelSftp getChannelSftp() throws JSchException
{
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
Session session;
session = jsch.getSession(VENDOR1_USERID, VENDOR1_SERVER, VENDOR1_PORT);
session.setPassword(VENDOR1_PASSWORD);
session.setConfig(config);
session.connect();
ChannelSftp channelSftp = null;
Channel channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp) channel;
return channelSftp;
}
But after the SFTP operation I need to disconnect from channel and session both.
With above method, though I can disconnect from Channel
in the calling method but I can't disconnect from Session
as I don't have its instance which might be a leak so I now separated that into getSession()
method and now ChannelSftp
creation is duplicated in all methods.
What is better way to design/refactor it?
private Session getSession() throws JSchException
{
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
Session session;
session = jsch.getSession(VENDOR1_USERID, VENDOR1_SERVER, VENDOR1_PORT);
session.setPassword(VENDOR1_PASSWORD);
session.setConfig(config);
session.connect();
return session;
}
Calling Method example: - Duplicated code indicated
public void sftp(File file) throws SftpException, FileNotFoundException, JSchException
{
Session session = getSession();
/* Duplicate code START*/
if ( session == null ) throw new SftpException(0 , "Service: Session is NULL");
ChannelSftp channelSftp = null;
Channel channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp) channel;
/* Duplicate code END*/
channelSftp.cd(VENDOR1_PATH);
channelSftp.put(new FileInputStream(file), file.getName());
channelSftp.disconnect();
session.disconnect();
}
If you use the SFTP session frequently enough, you should not recreate it for every operation. Opening an SSH/SFTP connection is very CPU demanding, both for the client and the server. It's quite a waste to shutdown a connection, if you are going to need a new one shortly.
So consider opening a single shared session and channel at the beginning of your "application" and reuse it for all operations.
To answer your actual session: I'd introduce another class that owns both Session
and ChannelSftp
(with methods like getSession()
and getChannel()
) and return that from the factory method.
Though actually, there's getSession
method in the Channel
class.
来源:https://stackoverflow.com/questions/47451879/getting-session-and-sftp-channel-in-java-using-jsch-library