【问题标题】:Get String from Spring FTP streaming Inbound Channel Adapter从 Spring FTP 流式入站通道适配器获取字符串
【发布时间】:2016-10-19 15:21:41
【问题描述】:

我有以下代码可以正常将文件从 FTP 服务器检索到流中,但我需要获取每个文件的字符串,似乎我需要使用 Transformer 传递一个字符集,但我缺少什么?究竟如何获取传输的每个文件的内容字符串?

提前非常感谢

@SpringBootApplication
@EnableIntegration
public class FtpinboundApp extends SpringBootServletInitializer implements WebApplicationInitializer {

    final static Logger logger = Logger.getLogger(FtpinboundApp.class);

    public static void main(String[] args) {
        SpringApplication.run(FtpinboundApp.class, args);
    }

    @Bean
    public SessionFactory<FTPFile> ftpSessionFactory() {
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost("X.X.X.X");
        sf.setPort(21);
        sf.setUsername("xxx");
        sf.setPassword("XXX");
        return new CachingSessionFactory<FTPFile>(sf);
    }


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

            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                System.out.println("trasnferred file:" + message.getPayload());

            }

        };
    }

    @Bean
    @InboundChannelAdapter(value = "stream", poller = @Poller(fixedRate = "1000"))
    public MessageSource<InputStream> ftpMessageSource() {

        FtpStreamingMessageSource messageSource = new FtpStreamingMessageSource(template(), null);
        messageSource.setRemoteDirectory("/X/X/X");
        messageSource.setFilter(new FtpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "streaming"));
        return messageSource;
    }

    @Bean
       @Transformer(inputChannel = "stream", outputChannel = "data")
       public org.springframework.integration.transformer.Transformer transformer() {
           return new StreamTransformer("UTF-8");
       }

       @Bean
       public FtpRemoteFileTemplate template() {
           return new FtpRemoteFileTemplate(ftpSessionFactory());
       }


    @Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata defaultPoller() {
        PollerMetadata pollerMetadata = new PollerMetadata();
        pollerMetadata.setTrigger(new PeriodicTrigger(5000));
        return pollerMetadata;
    }

}

【问题讨论】:

    标签: spring ftp stream spring-integration


    【解决方案1】:

    使用StreamTransformer 将整个文件作为单个字符串获取,或使用FileSplitter 获取每一行的消息。

    编辑(过滤器配置)

    @Bean
    @InboundChannelAdapter(channel = "stream")
    public MessageSource<InputStream> ftpMessageSource() {
        FtpStreamingMessageSource messageSource = new FtpStreamingMessageSource(template(), null);
        messageSource.setRemoteDirectory("ftpSource/");
        messageSource.setFilter(filter());
        return messageSource;
    }
    
    public FileListFilter<FTPFile> filter() {
        CompositeFileListFilter<FTPFile> filter = new CompositeFileListFilter<>();
        filter.addFilter(new FtpSimplePatternFileListFilter("*.txt"));
        filter.addFilter(acceptOnceFilter());
        return filter;
    }
    
    @Bean
    public FtpPersistentAcceptOnceFileListFilter acceptOnceFilter() {
        FtpPersistentAcceptOnceFileListFilter filter = new FtpPersistentAcceptOnceFileListFilter(meta(),
                "streaming"); // keys will be, e.g. "streamingfoo.txt"
        filter.setFlushOnUpdate(true);
        return filter;
    }
    
    @Bean
    public ConcurrentMetadataStore meta() {
        PropertiesPersistingMetadataStore meta = new PropertiesPersistingMetadataStore();
        meta.setBaseDirectory("/tmp/foo");
        meta.setFileName("ftpStream.properties");
        return meta;
    }
    

    EDIT2 - 删除带有建议的远程文件

    @ServiceActivator(inputChannel = "data", adviceChain = "after")
    @Bean
    public MessageHandler handle() {
        return System.out::println;
    }
    
    @Bean
    public ExpressionEvaluatingRequestHandlerAdvice after() {
        ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
        advice.setOnSuccessExpression(
                "@template.remove(headers['file_remoteDirectory'] + headers['file_remoteFile'])");
        advice.setPropagateEvaluationFailures(true);
        return advice;
    }
    

    【讨论】:

    • 加里,谢谢,实际上我有:@Bean @Transformer(inputChannel = "stream", outputChannel = "data") public org.springframework.integration.transformer.Transformer transformer() { return new StreamTransformer ("UTF-8"); } 但我不确定在代码中的何处使用它。
    • 您的服务激活器和转换器都订阅了stream - 这意味着消息将交替发送到每个 - 您需要将服务激活器订阅到转换器的输出通道。
    • 哦!我懂了。我现在明白了!谢谢 Gary,感谢您的慷慨,您能告诉我如何将流式消息源过滤器设置为仅从服务器获取某些文件吗?我在文档中找不到明确的(对我来说),它似乎与标准的 FTP 入站通道不同。
    • 查看我的答案的编辑。如果您从存储中删除了密钥 (prefix+filename),或者远程文件时间戳发生更改,则将重新获取该文件。
    • 您真的应该提出新问题,而不是不断向这个问题添加新问题。请参阅我的第二次编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多