In this article we will connect to SFTP server using only password as the authentication method.
We will use Apache's VFS library to establish the connection.
Following class show how to:
- Connect to SFTP server
- Navigate to a desired folder
- List of files in a folder
First we need to add the Apache VFS dependency to our project. For maven it can be added to the pom.xml file.
Latest dependency can be found at: https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.9.0</version>
</dependency>
Now let's look at the actual code, in SftpWithPassword class below.
/**
* This class uses Apache's VFS project to connect to remote SFTP server using
* username and password based authentication.
* <p>
* Maven Dependency: https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2
* Apache Commons-VFS Project: https://commons.apache.org/proper/commons-vfs/
*/
public class SftpWithPassword {
public static final String SFTP = "sftp";
/**
* Holds instance of remote SFTP folder.
*/
private FileObject fileObject;
/**
* Direct instantiation not allowed. Use {@link #connect(String, Integer, String, String)}
* method to initiate connection.
*
* @param fileObject
*/
private SftpWithPassword(FileObject fileObject) {
this.fileObject = fileObject;
}
/**
* Initiate connection to remote SFTP server
*
* @param host
* @param port
* @param userName
* @param password
* @return
*/
public static SftpWithPassword connect(String host,
Integer port,
String userName,
String password) throws URISyntaxException, FileSystemException {
URI sftpUri = createSftpUri(host, port, userName, password);
return new SftpWithPassword(VFS.getManager().resolveFile(sftpUri.toString()));
}
/**
* Navigate to specific folder in SFTP
*
* @param folderPath
* @return
*/
public SftpWithPassword cd(String folderPath) throws FileSystemException {
if (this.fileObject == null) {
throw new RuntimeException("SFTP connection not initiated.");
}
FileObject newFolder = this.fileObject.resolveFile(folderPath);
if (!newFolder.exists() || !newFolder.isFolder()) {
throw new RuntimeException("Path does not exist or is not a folder.");
}
this.fileObject = newFolder;
return this;
}
/**
* List all file names. Only file names are listed, not the folders.
*
* @return
*/
public List<String> listFiles() throws FileSystemException {
return ofNullable(this.fileObject.findFiles(SELECT_FILES))
.map(Arrays::asList)
.orElseGet(Collections::emptyList)
.stream()
.map(FileObject::getName)
.map(FileName::getBaseName)
.collect(Collectors.toList());
}
/**
* Create SFTP URI
*
* @param host
* @param port
* @param userName
* @param password
* @return
*/
private static URI createSftpUri(String host,
Integer port,
String userName,
String password) throws URISyntaxException {
String userInfo = userName + ":" + password;
return new URI(SFTP, userInfo, host, Objects.requireNonNullElse(port, -1), null, null, null);
}
}
Sample usage of the SftpWithPassword class would be as below
/**
* Sample usage of {@link SftpWithPassword} class
*/
class SftpWithPasswordTest {
/**
* Test that all files in movies folder are listed.
*
* @throws URISyntaxException
* @throws FileSystemException
*/
public void listAllFiles() throws URISyntaxException, FileSystemException {
List<String> files = SftpWithPassword.connect("localhost", 22, "admin", "password")
.cd("movies")
.listFiles();
Assertions.assertEquals(2, files.size());
}
}
0 comments:
Post a Comment