Home > Back-end >  Accessing file from SFTP without downloading it to local using Spring Integration
Accessing file from SFTP without downloading it to local using Spring Integration

Time:04-19

I currently have the following configuration:

    @Bean
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost(sftpHost);
    factory.setPort(sftpPort);
    factory.setUser(sftpUser);
    if (null != sftpPrivateKey) {
        factory.setPrivateKey(sftpPrivateKey);
        factory.setPrivateKeyPassphrase(sftpPrivateKeyPassphrase);
    } else {
        factory.setPassword(sftpPassword);
    }
    factory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<>(factory);
}

@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
    SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
    // fileSynchronizer.setDeleteRemoteFiles(true);
    fileSynchronizer.setRemoteDirectory(sftpRemoteDirectory);
    fileSynchronizer
            .setFilter(new SftpSimplePatternFileListFilter(sftpRemoteDirectoryFilter));
    return fileSynchronizer;
}

@Bean
@InboundChannelAdapter(channel = "fromSftpChannel", poller = @Poller(cron = "0/5 * * * * *"))
public MessageSource<File> sftpMessageSource() {
    SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
            sftpInboundFileSynchronizer());
    source.setLocalDirectory(new File(sftpLocalDirectory));
    source.setAutoCreateLocalDirectory(true);
    source.setLocalFilter(new AcceptOnceFileListFilter<>());
    return source;
}

@Bean
@ServiceActivator(inputChannel = "fromSftpChannel")
public MessageHandler resultFileHandler() {
    return message -> System.err.println(message.getPayload());
}

This one downloads anything from the remote directory to a local directory. But I have a rest controller and I would like to stream back a byte array of the file from the SFTP server instead of downloading it to a local machine. Is it possible in Spring Integration/Boot? Do you have some code examples, please?

CodePudding user response:

Since you say that you have a REST controller to make requests for SFTP files, then I would recommend to look into an SftpOutboundGateway, which indeed designed for requests and replies. See its Command.GET and Option.STREAM:

    /**
     * (-stream) Streaming 'get' (returns InputStream); user must call {@link Session#close()}.
     */
    STREAM("-stream"),

See more in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#using-the-get-command

Not sure what led you to SftpInboundFileSynchronizingMessageSource for your request-reply task...

CodePudding user response:

You can use the FtpClient and call retrieveFileStream to read a file from the remote sftp server. See https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#retrieveFileStream-java.lang.String-

  • Related