Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll discuss how to upload and download files from a remote server using SFTP in Java.

We’ll use three different libraries: JSch, SSHJ, and Apache Commons VFS.

2. Using JSch

First, let’s see how to upload and download files from a remote server using the JSch library.

2.1. Maven Configuration

We’ll need to add the jsch dependency to our pom.xml:

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.2.16</version>
</dependency>

The latest version of jsch can be found on Maven Central.

2.2. Setting Up JSch

Now we’ll set up JSch.

JSch enables us to use either Password Authentication or Public Key Authentication to access a remote server. In this example, we’ll use password authentication:

private ChannelSftp setupJsch() throws JSchException {
    JSch jsch = new JSch();
    jsch.setKnownHosts("/Users/john/.ssh/known_hosts");
    Session jschSession = jsch.getSession(username, remoteHost);
    jschSession.setPassword(password);
    jschSession.connect();
    return (ChannelSftp) jschSession.openChannel("sftp");
}

In the example above, the remoteHost represents the name or IP address of the remote server (i.e. example.com). We can define the variables used in the test as:

private String remoteHost = "HOST_NAME_HERE";
private String username = "USERNAME_HERE";
private String password = "PASSWORD_HERE";

We can also generate the known_hosts file using the following command:

ssh-keyscan -H -t rsa REMOTE_HOSTNAME >> known_hosts

2.3. Uploading a File With JSch

To upload a file to the remote server, we’ll use the method ChannelSftp.put():

@Test
public void whenUploadFileUsingJsch_thenSuccess() throws JSchException, SftpException {
    ChannelSftp channelSftp = setupJsch();
    channelSftp.connect();
 
    String localFile = "src/main/resources/sample.txt";
    String remoteDir = "remote_sftp_test/";
 
    channelSftp.put(localFile, remoteDir + "jschFile.txt");
 
    channelSftp.exit();
}

In this example, the first parameter of the method represents the local file to be transferred, src/main/resources/sample.txt, while remoteDir is the path of the target directory at the remote server.

2.4. Downloading a File With JSch

We can also download a file from the remote server using ChannelSftp.get():

@Test
public void whenDownloadFileUsingJsch_thenSuccess() throws JSchException, SftpException {
    ChannelSftp channelSftp = setupJsch();
    channelSftp.connect();
 
    String remoteFile = "welcome.txt";
    String localDir = "src/main/resources/";
 
    channelSftp.get(remoteFile, localDir + "jschFile.txt");
 
    channelSftp.exit();
}

The remoteFile is the path of the file to be downloaded, and localDir represents the path of the target local directory.

3. Using SSHJ

Next, we’ll use the SSHJ library to upload and download files from a remote server.

3.1. Maven Configuration

First, we’ll add the dependency to our pom.xml:

<dependency>
    <groupId>com.hierynomus</groupId>
    <artifactId>sshj</artifactId>
    <version>0.38.0</version>
</dependency>

The latest version of sshj can be found on Maven Central.

3.2. Setting Up SSHJ

Then we’ll set up the SSHClient.

SSHJ also allows us to use Password or Public Key Authentication to access the remote server.

We’ll use the Password Authentication in our example:

private SSHClient setupSshj() throws IOException {
    SSHClient client = new SSHClient();
    client.addHostKeyVerifier(new PromiscuousVerifier());
    client.connect(remoteHost);
    client.useCompression();
    client.authPassword(username, password);
    return client;
}

We have also set up the client to use Zlib compression, in order to enhance the performance of the transferring. This can be pretty useful If we need to transfer large files.

3.3. Uploading a File With SSHJ

Similar to JSch, we’ll use the SFTPClient.put() method to upload a file to the remote server:

@Test
public void whenUploadFileUsingSshj_thenSuccess() throws IOException {
    SSHClient sshClient = setupSshj();
    SFTPClient sftpClient = sshClient.newSFTPClient();
 
    sftpClient.put(localFile, remoteDir + "sshjFile.txt");
 
    sftpClient.close();
    sshClient.disconnect();
}

We have two new variables here to define:

private String localFile = "src/main/resources/input.txt";
private String remoteDir = "remote_sftp_test/";

3.4. Downloading a File With SSHJ

The same goes for downloading a file from the remote server; we’ll use SFTPClient.get():

@Test
public void whenDownloadFileUsingSshj_thenSuccess() throws IOException {
    SSHClient sshClient = setupSshj();
    SFTPClient sftpClient = sshClient.newSFTPClient();
 
    sftpClient.get(remoteFile, localDir + "sshjFile.txt");
 
    sftpClient.close();
    sshClient.disconnect();
}

And we’ll add the two variables used above:

private String remoteFile = "welcome.txt";
private String localDir = "src/main/resources/";

4. Using Apache Commons VFS

Finally, we’ll use Apache Commons VFS to transfer files to a remote server.

In fact, Apache Commons VFS uses JSch library internally.

4.1. Maven Configuration

We need to add the commons-vfs2 dependency to our pom.xml:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-vfs2</artifactId>
    <version>2.9.0</version>
</dependency>

The latest version of commons-vfs2 can be found on Maven Central.

4.2. Uploading a File With Apache Commons VFS

Apache Commons VFS is a little different.

We’ll use a FileSystemManager to create FileObjects from our target files, then use the FileObjects to transfer our files.

In this example, we’ll upload a file by using the method FileObject.copyFrom():

@Test
public void whenUploadFileUsingApacheVfs_thenSuccess() throws IOException {
    FileSystemManager manager = VFS.getManager();
 
    FileObject local = manager.resolveFile(
      System.getProperty("user.dir") + "/" + localFile);
    FileObject remote = manager.resolveFile(
      "sftp://" + username + ":" + password + "@" + remoteHost + "/" + remoteDir + "vfsFile.txt");
 
    remote.copyFrom(local, Selectors.SELECT_SELF);
 
    local.close();
    remote.close();
}

Note that the local file path should be absolute, and the remote file path should start with sftp://username:password@remoteHost.

4.3. Downloading a File With Apache Commons VFS

Downloading a file from a remote server is very similar; we’ll also use FileObject.copyFrom() to copy localFile from remoteFile:

@Test
public void whenDownloadFileUsingApacheVfs_thenSuccess() throws IOException {
    FileSystemManager manager = VFS.getManager();
 
    FileObject local = manager.resolveFile(
      System.getProperty("user.dir") + "/" + localDir + "vfsFile.txt");
    FileObject remote = manager.resolveFile(
      "sftp://" + username + ":" + password + "@" + remoteHost + "/" + remoteFile);
 
    local.copyFrom(remote, Selectors.SELECT_SELF);
 
    local.close();
    remote.close();
}

5. Conclusion

In this article, we learned how to upload and download files from a remote SFTP server in Java. To do this, we used multiple libraries: JSch, SSHJ, and Apache Commons VFS.

The full source code can be found over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.