views:

15317

answers:

13

What is the best was to retrieve a file from a server using SFTP (as opposed to FTPS) using Java? I'll leave the particular definition of best up to you but in my mind it should include free :)

+12  A: 

This was the solution I came up with http://sourceforge.net/projects/sshtools/ (most error handling omitted for clarity). This is an excerpt from my blog

SshClient ssh = new SshClient();
ssh.connect(host, port);
//Authenticate
PasswordAuthenticationClient passwordAuthenticationClient = new PasswordAuthenticationClient();
passwordAuthenticationClient.setUsername(userName);
passwordAuthenticationClient.setPassword(password);
int result = ssh.authenticate(passwordAuthenticationClient);
if(result != AuthenticationProtocolState.COMPLETE){
     throw new SFTPException("Login to " + host + ":" + port + " " + userName + "/" + password + " failed");
}
//Open the SFTP channel
SftpClient client = ssh.openSftpClient();
//Send the file
client.put(filePath);
//disconnect
client.quit();
ssh.disconnect();
David Hayes
j2ssh is pretty buggy
Bruce Blackshaw
+17  A: 

Another option is to consider looking at the JSch library. JSch seems to be the preferred library for a few large open source projects, including Eclipse, Ant and Apache Commons HttpClient, amongst others.

It supports both user/pass and certificate-based logins nicely, as well as all a whole host of other yummy SSH2 features.

Here's a simple remote file retrieve over SFTP. Error handling is left as an exercise for the reader :-)

JSch jsch = new JSch();

String knownHostsFilename = "/home/username/.ssh/known_hosts";
jsch.setKnownHosts( knownHostsFilename );

Session session = jsch.getSession( "remote-username", "remote-host" );    
{
  // "interactive" version
  // can selectively update specified known_hosts file 
  // need to implement UserInfo interface
  // MyUserInfo is a swing implementation provided in 
  //  examples/Sftp.java in the JSch dist
  UserInfo ui = new MyUserInfo();
  session.setUserInfo(ui);

  // OR non-interactive version. Relies in host key being in known-hosts file
  session.setPassword( "remote-password" );
}

session.connect();

Channel channel = session.openChannel( "sftp" );
channel.connect();

ChannelSftp sftpChannel = (ChannelSftp) channel;

sftpChannel.get("remote-file", "local-file" );
// OR
InputStream in = sftpChannel.get( "remote-file" );
  // process inputstream as needed

sftpChannel.exit();
session.disconnect();
Cheekysoft
+6  A: 

A nice abstraction on top of Jsch is Apache commons-vfs which offers a virtual filesystem API that makes accessing and writing SFTP files almost transparent. Worked well for us.

Boris Terzic
is it possible to use pre-shared keys in combination with commons-vfs?
bene
+1  A: 

The best solution I've found is Paramiko. There's a Java version.

Brian Clapper
+1  A: 

You also have JFileUpload with SFTP add-on (Java too): http://www.jfileupload.com/products/sftp/index.html

+1  A: 

Try edtFTPj/PRO, a mature, robust SFTP client library that supports connection pools and asynchronous operations. Also supports FTP and FTPS so all bases for secure file transfer are covered.

Bruce Blackshaw
+1  A: 

I use this SFTP API called Zehon, it's great, so easy to use with a lot of sample code. Here is the site http://www.zehon.com

A: 

Cheekysoft,

I noticed - while using Jsch - removing files on the sftp-server does not work. Also renaming files does not work too.

Any ideas please???

Andy

andy
A: 

sshj has a complete implementation of SFTP version 3 (what OpenSSH implements)

shikhar
+1  A: 

Below is an example using Apache Common VFS:

FileSystemOptions fsOptions = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fsOptions, "no");
FileSystemManager fsManager = VFS.getManager();
String uri = "sftp://user:password@host:port/absolute-path";
FileObject fo = fsManager.resolveFile(uri, fsOptions);
Chris J
A: 

You can also have a look to JFileUpload with SFTP add-on if you need something running in browser: http://www.jfileupload.com/products/sftp/index.html

fileuploader
+3  A: 

Here is the complete source code of an example using JSch without having to worry about the ssh key checking.

import com.jcraft.jsch.*;

public class TestJSch {
    public static void main(String args[]) {
        JSch jsch = new JSch();
        Session session = null;
        try {
            session = jsch.getSession("username", "127.0.0.1", 22);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setPassword("password");
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftpChannel = (ChannelSftp) channel;
            sftpChannel.get("remotefile.txt", "localfile.txt");
            sftpChannel.exit();
            session.disconnect();
        } catch (JSchException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }
}
Iraklis
A: 

its ok for transferring files but what about directories any answer

chandra shekhar