Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> 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.1.55</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";

Also, we can 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

Now, 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, for example, 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.27.0</version>
</dependency>

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

3.2. Setting Up SSHJ

Next, 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.authPassword(username, password);
    return client;
}

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

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 let's 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.

Actually, 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.4</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 method FileObject.copyFrom():

@Test
public void whenUploadFileUsingVfs_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:[email protected]

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 whenDownloadFileUsingVfs_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. For this, we used multiple libraries: JSch, SSHJ, and Apache Commons VFS.

The full source code can be found over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!