【问题标题】:How to Disconnect FTP server connection after Files downloaded?文件下载后如何断开 FTP 服务器连接?
【发布时间】:2016-10-24 14:03:42
【问题描述】:

使用 Spring FTP 集成和注释配置,我从 FTP 服务器下载了文件。下载后,我们的应用程序仍然触发连接服务器并查找任何新添加的文件,如果添加了任何文件,它将从服务器下载。但是我不需要在第一次连接或第一次下载后保持 FTP 服务器会话处于活动状态并断开服务器。

代码:

public class FtpServices {

    @Bean(name="ftpSessionFactory")
    public DefaultFtpSessionFactory ftpSessionFactory() {
        System.out.println("session");

        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost("localhost");
        sf.setPort(21);
        sf.setUsername("user");
        sf.setPassword("password");

        return sf;
    }

    @Bean
    public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
        System.out.println("2");
        FtpInboundFileSynchronizer fileSynchronizer = new FtpInboundFileSynchronizer(ftpSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(false);
        fileSynchronizer.afterPropertiesSet();
        fileSynchronizer.setRemoteDirectory("/test/");
       // fileSynchronizer.setFilter(new FtpSimplePatternFileListFilter("*.docx"));
        fileSynchronizer.setFilter(filter);
        return fileSynchronizer;
    }

    @Bean()
    @InboundChannelAdapter(value="ftpChannel", poller = @Poller(fixedDelay = "50", maxMessagesPerPoll = "1"))
    public FtpInboundFileSynchronizingMessageSource ftpMessageSource() {
        System.out.println(3);
        FtpInboundFileSynchronizingMessageSource source =
                new FtpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("D:/Test-downloaded/"));
        //source.stop();
        return source;
    }

    @Bean
    @ServiceActivator(inputChannel = "ftpChannel", requiresReply="false")
    public MessageHandler handler() {
        System.out.println(4);
        MessageHandler handler =  new MessageHandler() {

            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                System.out.println(message.getPayload()+" @ServiceActivator");
                System.out.println(" Message Header :"+message.getHeaders());
            }
        };
        return handler;
    }

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

        PollerMetadata pollerMetadata = new PollerMetadata();
        pollerMetadata.setTrigger(triggerOnlyOnce());
        return pollerMetadata;
    }

}

我还重写了 AbtractFTPSessionFactory.java 来测试 FTP 服务器的连接和断开过程。

protected void postProcessClientAfterConnect(T t) throws IOException {
    System.out.println("After connect");
}

protected void postProcessClientBeforeConnect(T client) throws IOException {
    System.out.println("Before connect");
}

控制台:

    INFO : org.springframework.context.support.DefaultLifecycleProcessor - Starting beans in phase -2147483648
    INFO : org.springframework.context.support.DefaultLifecycleProcessor - Starting beans in phase 0
    Before connect
    After connect
    D:\Test-downloaded\demo 1.txt @ServiceActivator
     Message Header :{id=e4a1fd7f-0bbf-9692-f70f-b0ac68b4dec4, timestamp=1477317086272}
    D:\Test-downloaded\demo.txt @ServiceActivator
     Message Header :{id=9115ee92-12b4-bf1f-d592-9c13bf7a27fa, timestamp=1477317086324}
    Before connect
    After connect
    Before connect
    After connect
    Before connect
    After connect
    Before connect
    After connect
    Before connect
    After connect
    Before connect
    After connect

谢谢。

【问题讨论】:

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


    【解决方案1】:

    这确实是任何@InboundChannelAdapter 的目的:定期轮询目标系统以获取新数据。

    我们有时建议OnlyOnceTrigger

    public class OnlyOnceTrigger implements Trigger {
    
        private final AtomicBoolean done = new AtomicBoolean();
    
        @Override
        public Date nextExecutionTime(TriggerContext triggerContext) {
               return !this.done.getAndSet(true) ? new Date() : null;
        }
    
    }
    

    但这可能不适用于您的情况,因为源 FTP 目录中可能还没有所需的文件。

    因此,我们必须轮询,直到您收到所需的文件并在满足该条件时.stop() 适配器。

    为此,您可以使用任何下游逻辑来确定状态或考虑实现AbstractMessageSourceAdvice 以注入@PollerPollerMetadatahttp://docs.spring.io/spring-integration/reference/html/messaging-channels-section.html#conditional-pollers

    【讨论】:

    • 它工作正常,但它仍然触发 AbstractMessageSourceAdvice 子类,并且在一些业务逻辑之后,我从 beforeReceive(MessageSource> source) 返回 false,所以它没有触发 FTP 服务器。是否会影响我们的应用程序性能。
    • 好吧,不多,但完全避免触发,您可以考虑停止入站通道适配器端点
    • 如果本地目录有旧文件,那么我们的应用程序没有连接到 FTP 服务器。如果不是这意味着我们的本地目录是空的,那么它工作正常。他们有什么理由吗?以及如何克服这一点。
    • 为此您可以考虑使用持久化localFilter,它会在重启后跳过已处理的文件并转到FTP。
    猜你喜欢
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    相关资源
    最近更新 更多