Spring 与 Spring Boot 集成 SFTP 示例

tjh*_*s66 6 java sftp spring-integration

我们正在为 Spring 应用程序使用最新的 Spring Boot,并为 SFTP 使用最新的 Spring Integration。我访问过 Spring Integration SFTP 文档站点,并按原样采用了 Spring Boot 配置:

 @Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost("localhost");
    factory.setPort(port);
    factory.setUser("foo");
    factory.setPassword("foo");
    factory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<LsEntry>(factory);
}

@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
    SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
    fileSynchronizer.setDeleteRemoteFiles(false);
    fileSynchronizer.setRemoteDirectory("/");
    fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xml"));
    return fileSynchronizer;
}

@Bean
@InboundChannelAdapter(channel = "sftpChannel")
public MessageSource<File> sftpMessageSource() {
    SftpInboundFileSynchronizingMessageSource source =
            new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
    source.setLocalDirectory(new File("ftp-inbound"));
    source.setAutoCreateLocalDirectory(true);
    source.setLocalFilter(new AcceptOnceFileListFilter<File>());
    return source;
}

@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
    return new MessageHandler() {

        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            System.out.println(message.getPayload());
        }

    };
}
Run Code Online (Sandbox Code Playgroud)

让我澄清一下,剪切和粘贴后,会运行一些单元测试。但是,在加载应用程序上下文时出现错误消息,因为轮询不存在。

当我用 google 搜索该错误时,StackOverflow 上的其他帖子说我还必须在加载应用程序上下文时添加以删除此错误消息。

@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {

    PollerMetadata pollerMetadata = new PollerMetadata();
    pollerMetadata.setTrigger(new PeriodicTrigger(60));
    return pollerMetadata;
}
Run Code Online (Sandbox Code Playgroud)

当我添加此代码时,至少我的构建可以工作并且测试可以运行,因为应用程序上下文现在已正确加载。

现在我正在寻找有关如何使其工作和移动文件的代码示例?GitHub 上的 Spring Integration SFTP 示例还可以,但还不是很好......远非如此。

基本 Spring 集成示例展示了如何从 SFTP 服务器读取文件(如果使用 application-context.xml 文件配置数据)。使用 Spring Boot 配置的示例在哪里,然后是从该服务器读取的代码以及测试的代码?

据我所知,无论您使用 Java 类进行 Spring Boot 配置还是 application-context.xml 文件...对于自动连接的 SFTP 通道和某些入站通道适配器,工作代码都应该以相同的方式工作。

所以这是代码,我正在努力工作:

@Component
@Profile("sftpInputFetch")
public class SFTPInputFetcher implements InputFetcher
{
    // The PollableChannel seems fine
    @Autowired
    PollableChannel sftpChannel;

    @Autowired
    SourcePollingChannelAdapter sftpChannelAdapter;

@Override
public Stream<String> fetchLatest() throws FileNotFoundException
{
    Stream<String> stream = null;
    sftpChannelAdapter.start();
    Message<?> received = sftpChannel.receive();
    File file = (File)received.getPayload();
    // get Stream<String> from file
    return stream;
}
Run Code Online (Sandbox Code Playgroud)

目前,“sftpChannelAdapter.start();” 是我遇到麻烦的部分。此实现未找到“SourcePollingChannelAdapter”类。

如果这是在经典 XML 应用程序上下文中使用“id”定义的,那么此代码可以很好地自动装配。使用 Spring Boot 配置,您似乎无法为 bean 定义“id”。

这只是因为我缺乏关于如何从使用带有代码中注释的传统应用程序上下文 XML 文件转换为使用完整的 Spring Boot 应用程序上下文配置文件的知识。

非常感谢任何对此的帮助。谢谢!

Gar*_*ell 6

我不明白这个问题;你说

我必须添加...才能使其正常工作

进而

现在我正在寻找有关如何使其工作的代码示例?

什么不起作用?

您还可以使用

@InboundChannelAdapter(value = "sftpChannel", poller = @Poller(fixedDelay = "5000"))
Run Code Online (Sandbox Code Playgroud)

而不是添加默认轮询器定义。

我们将修复缺少的轮询器配置的文档

编辑

我刚刚将代码复制到新的启动应用程序中(使用轮询器配置),它按预期工作。

@SpringBootApplication
public class SftpJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(SftpJavaApplication.class).web(false).run(args);
    }

    @Bean
    public SessionFactory<LsEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost("...");
        factory.setPort(22);
        factory.setUser("...");
        factory.setPassword("...");
        factory.setAllowUnknownKeys(true);
        return new CachingSessionFactory<LsEntry>(factory);
    }

    @Bean
    public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
        SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(false);
        fileSynchronizer.setRemoteDirectory("foo");
        fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.txt"));
        return fileSynchronizer;
    }

    @Bean
    @InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = "5000"))
    public MessageSource<File> sftpMessageSource() {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                sftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("ftp-inbound"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        return source;
    }

    @Bean
    @ServiceActivator(inputChannel = "sftpChannel")
    public MessageHandler handler() {
        return new MessageHandler() {

            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                System.out.println(message.getPayload());
            }

        };
    }

}
Run Code Online (Sandbox Code Playgroud)

结果:

16:57:59.697 [task-scheduler-1] WARN  com.jcraft.jsch - Permanently added '10.0.0.3' (RSA) to the list of known hosts.
ftp-inbound/bar.txt
ftp-inbound/baz.txt
Run Code Online (Sandbox Code Playgroud)