Spring Integration: SFTP Upload Example using Key-Based Authentication 5

This example will demonstrate how to use Spring Integration for uploading files to a remote SFTP server. Two possible authentications could be used, i.e. public key or password.

Technologies used:

  1. Spring Boot 1.5.2.RELEASE
  2. Spring Integration 4.3.8.RELEASE (managed by Spring Boot)
  3. Spring 4.3.7.RELEASE (managed by Spring Boot)

Quick overview:

  1. Create SFTP Session Factory, i.e. DefaultSftpSessionFactory
  2. Create and setup SftpMessageHandler
  3. Create UploadGateway as an entry point to upload any file

1. Project Structure

A final project directory structure.
Project Structure of Spring Integration project

2. SftpConfig using Java Configuration

We have to configure SFTP Session Factory (DefaultSftpSessionFactory) with all required parameters, i.e. host, IP port, username and password (or private key with a passphrase).

After that, we have to configure an appropriate MessageHandler, i.e. SftpMessageHandler in our case. It is responsible for uploading any incoming file to a remote SFTP server, so we must provide a remote directory path and a filename to be used on a remote server.

MessageHandler is a part of the Spring Integration, so we have to create a gateway between Spring Integration world (i.e. a world using channels, channel subscribers etc.) and the well-known world of simple beans. So the following annotation MessagingGateway on the interface UploadGateway will create a simple bean possible to be used anywhere you want to upload a file by calling upload method only.

public class SftpConfig {

    private String sftpHost;

    private int sftpPort;

    private String sftpUser;

    private Resource sftpPrivateKey;

    private String sftpPrivateKeyPassphrase;

    private String sftpPasword;

    private String sftpRemoteDirectory;

    public SessionFactory<LsEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        if (sftpPrivateKey != null) {
        } else {
        return new CachingSessionFactory<LsEntry>(factory);

    @ServiceActivator(inputChannel = "toSftpChannel")
    public MessageHandler handler() {
        SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
        handler.setRemoteDirectoryExpression(new LiteralExpression(sftpRemoteDirectory));
        handler.setFileNameGenerator(new FileNameGenerator() {
            public String generateFileName(Message<?> message) {
                if (message.getPayload() instanceof File) {
                    return ((File) message.getPayload()).getName();
                } else {
                    throw new IllegalArgumentException("File expected as payload.");
        return handler;

    public interface UploadGateway {

        @Gateway(requestChannel = "toSftpChannel")
        void upload(File file);


3. Setup Spring Boot with Spring Integration

I have used Spring Boot in my example, so annotation @SpringBootApplication is obvious. The more interesting annotation is @IntegrationComponentScan and @EnableIntegration which will enable all other configurations used in the previous configuration file.

public class SpringSftpUploadDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSftpUploadDemoApplication.class, args);

4. Example of Usage

Here you can see a basic usage of our UploadGateway. I have created an integration test using a real SFTP server with enabled public key authentication (i.e. without password).

@TestPropertySource(properties = { "sftp.port = 10022" })
public class SpringSftpUploadDemoApplicationTests {

    private UploadGateway gateway;

    private static EmbeddedSftpServer server;

    private static Path sftpFolder;

    public static void startServer() throws Exception {
        server = new EmbeddedSftpServer();
        sftpFolder = Files.createTempDirectory("SFTP_UPLOAD_TEST");
        // Starting SFTP
        if (!server.isRunning()) {

    public void cleanSftpFolder() throws IOException {

    public void testUpload() throws IOException {
        // Prepare phase
        Path tempFile = Files.createTempFile("UPLOAD_TEST", ".csv");

        // Prerequisites
        assertEquals(0, Files.list(sftpFolder).count());

        // test phase

        // Validation phase
        List<Path> paths = Files.list(sftpFolder).collect(Collectors.toList());
        assertEquals(1, paths.size());
        assertEquals(tempFile.getFileName(), paths.get(0).getFileName());

    public static void stopServer() {
        if (server.isRunning()) {

The source code of this project could be found on my public Github profile.

Share this: