【问题标题】:Accessing file from SFTP without downloading it to local using Spring Integration使用 Spring Integration 从 SFTP 访问文件而不将其下载到本地
【发布时间】:2022-11-10 06:07:00
【问题描述】:

我目前有以下配置:

    @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());
}

这个从远程目录下载任何东西到本地目录。但我有一个休息控制器,我想从 SFTP 服务器流回文件的字节数组,而不是将其下载到本地机器。在 Spring Integration/Boot 中是否有可能?请问您有一些代码示例吗?

【问题讨论】:

  • 最好有一个像Stream getFile(final String path); 这样的例程,它确实从远程获取

标签: spring spring-boot spring-integration sftp


【解决方案1】:

既然您说您有一个 REST 控制器来请求 SFTP 文件,那么我建议您查看SftpOutboundGateway,它确实是为请求和回复而设计的。查看其Command.GETOption.STREAM

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

在文档中查看更多信息:https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#using-the-get-command

不确定是什么导致您使用SftpInboundFileSynchronizingMessageSource 处理您的请求-回复任务...

【讨论】:

  • Tbh 我一直在努力寻找从 SFTP 服务器下载文件的完整示例。我发现的唯一一个是使用 SftpInboundFileSynchronizingMessageSource 的这个。非常感谢您的文档!所以我需要类似下面的东西:@Bean @ServiceActivator(inputChannel = "sftpChannel") public MessageHandler handler() { return new SftpOutboundGateway(ftpSessionFactory(), "ls", "'my_remote_dir/'");但是在它之后我如何读取我的休息控制器中的特定文件?
  • 你有一个迷你 github 项目或任何可能有用的东西吗?
  • 有这个,但它是基于 XML 的:github.com/spring-projects/spring-integration-samples/tree/main/…。我不确定为什么是关于控制器的问题。我猜你在请求中有一个文件名,所以你只需将带有该文件名的Message 发送到该服务激活器的输入通道。您可能缺少远程目录的setRemoteDirectoryExpression()。并且 ctor 中的 expression 必须像 payload。仅仅因为您的请求消息有效负载将是执行 GET 命令的远程文件名。
【解决方案2】:

您可以使用FtpClient 并调用retrieveFileStream 从远程sftp 服务器读取文件。见https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#retrieveFileStream-java.lang.String-

【讨论】:

  • 所以你会建议不要使用 Spring 来完成这个?
  • 对于您描述的用例,我没有看到使用弹簧集成增加了任何价值。 Spring Integration 在后台使用 FTPClient。 FTPClient 有一个retrieveFile 方法,该方法将直接写入OutputStream。
【解决方案3】:

我认为您可以通过使用RemoteFileTemplate 来实现这一点

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多