【问题标题】:Spring Integration with SFTPSpring 与 SFTP 的集成
【发布时间】:2019-06-25 15:49:58
【问题描述】:

我正在构建一个小微服务来从 SFTP 文件服务器访问文件。我决定使用 Spring Integration SFTP 来完成工作。我是 Spring Integration 的新手,对它的工作原理感到困惑。

我的目标是在 SFTP 服务器上的目录中获取文件列表并将它们呈现给用户界面。从那里,用户将选择一个文件进行下载,我将使用文件名将文件从 SFTP 服务器流式传输到用户界面。

我正在使用以下确实有效的代码。

Entire class to handle SFTP with SSH


@Slf4j
@Configuration
public class SftpConfig {
    @Value("${sftp.host}")
    private String sftpHost;
    @Value("${sftp.port:22}")
    private int sftpPort;
    @Value("${sftp.user}")
    private String sftpUser;
    @Value("${sftp.privateKey:#{null}}")
    private Resource sftpPrivateKey;
    @Value("${sftp.privateKeyPassphrase:}")
    private String sftpPrivateKeyPassphrase;
    @Value("${sftp.password:#{null}}")
    private String sftpPasword;
    @Value("${sftp.remote.directory:/}")
    private String sftpRemoteDirectory;

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

    @ServiceActivator(inputChannel = "ftpLS")
    @Bean
public SftpOutboundGateway getFtpLS() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "ls", "'" + sftpRemoteDirectory + "' + payload");
        gateway.setOption(AbstractRemoteFileOutboundGateway.Option.NAME_ONLY);
        return gateway;
    }

    @ServiceActivator(inputChannel = "ftpGet")
    @Bean
public SftpOutboundGateway getFtpGet() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "get", "'" + sftpRemoteDirectory + "' + payload");
        gateway.setOption(AbstractRemoteFileOutboundGateway.Option.STREAM);
        return gateway;
    }

    @MessagingGateway(defaultRequestChannel = "ftpLS")
    public interface FtpLS {
        List list(String directory);
    }

    @MessagingGateway(defaultRequestChannel = "ftpGet")
    public interface FtpGet {
        InputStream get(String fileName);
    }

}

运行

@Bean
public ApplicationRunner runner(SftpConfig.FtpLS ftpLS, SftpConfig.FtpGet ftpGet) {
    return args -> {
        List<String> list = ftpLS.list("139");
        System.out.println("Result:" + list);

        InputStream is = ftpGet.get("139/" + list.get(0));
        String theString = IOUtils.toString(is,"UTF-8");
        System.out.println("Result:" + theString);

    };
}

我的第一个问题是这是正确的方法吗?

其次,我是否需要两个接口才能使用两个不同的 SftpOutboundGateway?

最后,在执行 FtsGet 时是否有更好的方法来传递动态目录名称?现在我正在传递我正在将 139 与基本目录连接在一个字符串中,并通过接口传递它。

【问题讨论】:

    标签: spring spring-integration spring-integration-sftp


    【解决方案1】:

    这是正确的方法吗?

    是的,方法是正确的。虽然我建议不要将isSharedSession 用于网关,因为它可能会被不同用户从不同线程中使用。

    我需要两个接口吗?

    不,你真的可以有一个@MessagingGateway,但有几个方法标有自己的@Gateway 注释。

    有没有更好的方式传入动态目录?

    不,您的方法是正确的。没有像 working directory 这样的自动切换功能,就像我们在 FTP 中那样。

    【讨论】:

    • 所以通过不共享 FTP 会话,每个请求都会创建一个新会话,对吗?
    • 正确,但这是在不同请求之间不共享InputStream 的方式。在一个会话中,更多的阅读是阻塞的。在您不关闭当前的之前,您不能同时拥有另一个。您可以考虑使用CachingSessionFactory 包装器,但仍不共享目标会话。
    猜你喜欢
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多