spring - FileSystemPersistentAcceptOnceFileListFilter 与 CompositeFileListFilter 不兼容

标签 spring spring-integration

我正在使用 int-sftp:inbound-channel-adapter 观看多个远程文件夹,但本地过滤器遇到问题。

<int-sftp:inbound-channel-adapter id="inboundChannelPmse"
            session-factory="sftpSessionFactory"
            channel="chan"
            remote-directory="${rdir1}"
            filter="remoteUnseenFilter"
            preserve-timestamp="true"
            local-directory="${ldir1}"
            auto-create-local-directory="true"
            temporary-file-suffix=".writing"
            local-filter="localOnlyXmlFilter"
            delete-remote-files="false"
            local-filename-generator-expression="#this.toLowerCase()"
            >
        <int:poller fixed-rate="10000" max-messages-per-poll="-1" />
</int-sftp:inbound-channel-adapter>

<int-sftp:inbound-channel-adapter id="inboundChannelOfcomDefault"
            session-factory="sftpSessionFactory"
            channel="chan"
            remote-directory="${rdir2}"
            filter="remoteUnseenFilter"
            preserve-timestamp="true"
            local-directory="${ldir2}"
            auto-create-local-directory="true"
            temporary-file-suffix=".writing"
            local-filter="localOnlyCsvFilter"
            delete-remote-files="false"
            local-filename-generator-expression="#this.toLowerCase()"
            >
        <int:poller fixed-rate="10000" max-messages-per-poll="-1" />
</int-sftp:inbound-channel-adapter>

每个过滤器都是一个复合过滤器,其中包括 FileSystemPersistentAcceptOnceFileListFilter 和另一个过滤器,例如 IgnoreHiddenFileListFilter 和/或我的 ExtensionFileListFilter

<bean id="localOnlyXmlFilter"
    class="org.springframework.integration.file.filters.CompositeFileListFilter">
    <constructor-arg>
        <list>
            <bean
                class="org.springframework.integration.file.filters.IgnoreHiddenFileListFilter" />
            <bean
                class="uk.co.bigsoft.app.imports.filters.ExtensionFileListFilter">
                <constructor-arg value="xml" />
            </bean>
            <bean
                class="uk.co.bigsoft.app.imports.filters.PrefixFileListFilter">
                <constructor-arg index="0" value="pref2_" />
            </bean>
            <bean class="org.springframework.integration.file.filters.FileSystemPersistentAcceptOnceFileListFilter">
                <constructor-arg index="0" ref="localFileStore" />
                <constructor-arg index="1" name="prefix" value="" />
                <property name="flushOnUpdate" value="true" />
            </bean>
        </list>
    </constructor-arg>
</bean>

<bean id="localOnlyCsvFilter"
    class="org.springframework.integration.file.filters.CompositeFileListFilter">
    <constructor-arg>
        <list>
            <bean
                class="org.springframework.integration.file.filters.IgnoreHiddenFileListFilter" />
            <bean
                class="uk.co.bigsoft.app.imports.filters.ExtensionFileListFilter">
                <constructor-arg value="csv" />
            </bean>
            <bean
                class="uk.co.bigsoft.app.imports.filters.PrefixFileListFilter">
                <constructor-arg index="0" value="pref1_" />
            </bean>
            <bean class="org.springframework.integration.file.filters.FileSystemPersistentAcceptOnceFileListFilter">
                <constructor-arg index="0" ref="localFileStore" />
                <constructor-arg index="1" name="prefix" value="" />
                <property name="flushOnUpdate" value="true" />
            </bean>
        </list>
    </constructor-arg>
</bean>

文件下载正常,但根据 localOnlyXmlFilter 还是 localOnlyCsvFilter 首先运行,第二个运行的文件将看不到它,因为它已经被第一个运行的文件记住了!我想我真正想要的是本地过滤器沿着过滤器列表向下移动,并在过滤器为 false(或不返回任何条目)时停止,而不是无论如何运行所有过滤器(这似乎是对我来说有点毫无意义)。

有什么可以做到这一点吗?我一直在考虑重新组织过滤器,但总是遇到问题。

public class StoppingCompositeFileFilter extends AbstractFileListFilter<File> {

    private List<AbstractFileListFilter<File>> filters;

    public StoppingCompositeFileFilter(List<AbstractFileListFilter<File>> filters) {
    this.filters = filters;
    }

    @Override
    protected boolean accept(File file) {
    for (AbstractFileListFilter<File> filter : filters) {
       -->      // Fails to compile because accept() is abstract for AbstractFileListFilter
        if (!filter.accept(file)) {
            return false;
        }
    }
    return true;

    }
}

或者这个看起来过于复杂的:

class AnotherFilter implements FileListFilter<File> {

    private List<FileListFilter<File>> filters;


    @Override
    public List<File> filterFiles(File[] files) {
        List<File> keeping = new ArrayList<File>();
        for (File file : files) {
            for (FileListFilter<File> filter : filters) {
                keeping = filter.filterFiles(keeping.toArray(new File[keeping.size()]));
                if (keeping.size() == 0) {
                    return new ArrayList<File>();
                }
            }
        }
        return keeping;
    }

}

最佳答案

CompositeFileListFilter 逻辑如下所示:

public List<F> filterFiles(F[] files) {
    Assert.notNull(files, "'files' should not be null");
    List<F> results = new ArrayList<F>(Arrays.asList(files));
    for (FileListFilter<F> fileFilter : this.fileFilters) {
        List<F> currentResults = fileFilter.filterFiles(files);
        results.retainAll(currentResults);
    }
    return results;
}

所以,我认为你应该基于现有算法构建自己的逻辑,而不是发明一种可能是错误的或足够复杂的新设计。

还不确定您想要达到什么目的,但在我看来,AcceptOnce 必须位于列表中的第一位...

关于spring - FileSystemPersistentAcceptOnceFileListFilter 与 CompositeFileListFilter 不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32097961/

相关文章:

java - Spring Batch 集成——远程分块从属异常

java - spring 写回属性文件

jms - 如何在Spring集成中设置每个出站jms消息的优先级?

java - 访问 BeanFactoryPostProcessor 中的属性

Spring AMQP 模板

java - 如何通过控制总线启动入站 channel 适配器?

apache-kafka - 调度程序没有 channel 订阅者 - spring-cloud-stream-kafka

java - Spring集成中的分组和忽略消息

java - False 无法 Autowiring Intellij 错误

java - 使用 Spring 定义 Mongo 模式验证