Весенняя интеграция с SFTP - PullRequest
0 голосов
/ 25 июня 2019

Я создаю небольшой микросервис для доступа к файлам с файлового сервера 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 с базовым каталогом в строку и передаю его через интерфейс.

1 Ответ

2 голосов
/ 25 июня 2019

это правильный подход?

Да, подход правильный.Хотя я бы посоветовал не использовать isSharedSession для шлюза, поскольку он может использоваться разными пользователями из разных потоков.

мне нужны два интерфейса?

Нет, у вас действительно может быть один @MessagingGateway, но с несколькими методами, помеченными их собственными аннотациями @Gateway.

Есть ли лучший способ передачи в динамический каталог?

Нет, ваш подход правильный.Там нет чего-то вроде working directory для автоматического переключения, как мы можем сделать по FTP.

...