0

我已经配置了 spring SFTP 以将文件从远程路径汇集到本地,以处理一些作业,然后同时删除本地和远程文件。

下面的配置工作正常,除了本地文件删除,我没有找到任何配置来删除本地文件,比如delete-remote-files="true"

<bean id="sftpSessionFactory"
    class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory"
    p:host="${sftp.host}"
    p:port="${sftp.port}"
    p:user="${sftp.username}"
    p:password="${sftp.password}"
    p:allowUnknownKeys="${sftp.allowUnknownKeys}" />

<int:channel id="sftpChannel">
    <int:queue />
</int:channel>

<int-sftp:inbound-channel-adapter
    id="sftpInboundAdapter"
    channel="sftpChannel"
    session-factory="sftpSessionFactory"
    remote-directory="${sftp.remotedir}"
    local-directory="${sftp.localdir}"
    auto-create-local-directory="true"      
    delete-remote-files="true" 
    filename-pattern="*.TXT">
</int-sftp:inbound-channel-adapter>

<int:poller default="true" fixed-rate="${quartz.pick.repeatInterval}" max-messages-per-poll="${sftp.msg.per.poll}">
    <int:transactional synchronization-factory="syncFactory" />
</int:poller>   

<int:transaction-synchronization-factory id="syncFactory">
    <int:after-rollback expression="@acceptOnceFilter.remove(payload)"/>
</int:transaction-synchronization-factory>

<bean id="acceptOnceFilter" class="org.springframework.integration.file.filters.AcceptOnceFileListFilter"/>

<int:service-activator input-channel="sftpChannel" ref="msgHandler" method="handleMessage"/>

<bean id="transactionManager" class="org.springframework.integration.transaction.PseudoTransactionManager"/>

<bean id="fileNameGenerator" class="org.springframework.integration.file.DefaultFileNameGenerator" />

在这里,当文件从远程传输到本地时,服务激活器被调用。

当服务激活器完成工作时,如何配置删除本地文件?

编辑:从远程和本地删除有效负载都通过以下更改解决:

<int:transaction-synchronization-factory id="syncFactory">
    <int:after-commit expression="payload.delete()" channel="nullChannel"/>
    <int:after-rollback expression="@acceptOnceFilter.remove(payload)"/>
</int:transaction-synchronization-factory>
4

1 回答 1

3

在消息发送到流之后,入站适配器永远不会(自行)执行任何操作;它对下游流拓扑一无所知 - 异步切换等。远程删除是在获取文件之后和发送消息之前完成的。

由于您已经在使用伪事务,并且在轮询线程上执行所有操作,因此您可以使用after-commit-expression.

另一种技术是将 a 添加request-handler-advice到最终消费者(在您的情况下为服务激活器)。这在示例应用程序中进行retry-and-more演示。

编辑:

回应您的以下评论;不,用 SpEL 做两件事是不可能的 - 但是,你可以使用

<int:after-commit expression="payload" channel="postProcess"/>

postProcess并在通道下游的流量上做任何你想做的事情。

但是,我不清楚为什么要从过滤器中删除文件以获得成功和失败 - 你应该只使用 an AcceptAllFileListFilter

顺便说一句,我没有看到您acceptOnceFilter在此处的任何地方使用 - 您是否打算将其配置到local-filter属性中?

于 2016-03-27T14:49:23.363 回答