ftp出站通道适配器不传输相同的文件

时间:2014-12-02 07:42:27

标签: spring-integration

我的应用程序中有以下配置。我正在写一个文件到ftp文件夹并从ftp位置读取。

  1. 我想从ftp位置获取文件并将其保存在动态决定的目录中。这是通过使用两个链式通道适配器完成的。 ftp nbound通道适配器获取文件,将其放入本地目录,然后文件入站通道适配器获取文件并将其放入其最终目标。我需要为此过程过滤旧文件。 ftp入站通道适配器自定义过滤器在过滤方法中给了我FTPFile对象。此对象提供上次修改日期,而不是文件放入过滤器的日期。由于这个限制,我不得不使用文件入站通道适配器。
  2. 由于我不知道如何动态生成源目录,因此我使用普通的java代码将所需文件复制到ftp出站通道将其拾取并将其放在ftp位置的本地目录中。
  3. 这是配置:

        <bean id="fileNameGenerator" class="com.polling.util.FileNameGenerator"/>   
        <int-file:inbound-channel-adapter id="filesIn" directory="file:${paths.root}" channel="abc" filter="compositeFilter"  >
            <int:poller id="poller" fixed-rate="500" />
    
        </int-file:inbound-channel-adapter>
        <int:channel id="abc"/>
        <bean id="compositeFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
            <constructor-arg>
                <list>
                    <!-- Ensures that the file is whole before processing it -->
                    <bean class="com.polling.util.CustomFileFilter"/>
                    <!-- Ensures files are picked up only once from the directory -->
                    <bean class="org.springframework.integration.file.filters.AcceptOnceFileListFilter" />
                </list>
            </constructor-arg>
        </bean> 
        <int-file:outbound-channel-adapter channel="abc" id="filesOut"
            directory-expression="@outPathBean.getPath()"
            delete-source-files="true" filename-generator="fileNameGenerator" >
            <int-file:request-handler-advice-chain>
             <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
                <property name="onSuccessExpression" value="payload.delete()" />
              </bean>
        </int-file:request-handler-advice-chain>
            </int-file:outbound-channel-adapter>
       <bean id="ftpClientFactory"
        class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
        <property name="host" value="${ftp.ip}"/>
        <property name="port" value="${ftp.port}"/>
        <property name="username" value="${ftp.username}"/>
        <property name="password" value="${ftp.password}"/>
        <property name="clientMode" value="0"/>
        <property name="fileType" value="2"/>
        <property name="bufferSize" value="100000"/>
    </bean>
    
           <int:channel id="ftpChannel"/> 
    <int-ftp:inbound-channel-adapter id="ftpInbound"
        channel="ftpChannel"
        session-factory="ftpClientFactory"
        charset="UTF-8"
        local-directory="file:${paths.root}"
        delete-remote-files="true"
        temporary-file-suffix=".writing"
        remote-directory="${file.ftpfolder}"
    
        filter="compositeFilterRemote"
         preserve-timestamp="true"
         auto-startup="true">
        <int:poller fixed-rate="1000"/>
    </int-ftp:inbound-channel-adapter>
    <int-ftp:outbound-channel-adapter id="ftpOutbound"
        channel="ftpChannel"
        session-factory="ftpClientFactory"
        charset="UTF-8"
        remote-file-separator="/"
        auto-create-directory="true"
        remote-directory="${file.ftpfolder}" 
        use-temporary-file-name="true"
         temporary-file-suffix=".writing">
        <int-ftp:request-handler-advice-chain>
             <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
                <property name="onSuccessExpression" value="payload.delete()" />
              </bean>
        </int-ftp:request-handler-advice-chain>
      </int-ftp:outbound-channel-adapter>
    

    使用@ Gary的回答中的建议,我在ftp入站通道过滤器属性中添加了一个CustomFilter。这将检查文件名的正则表达式,如下所示

    @Override
    public List<FTPFile> filterFiles(FTPFile[] files)
    {
        List<FTPFile> ret = new ArrayList<FTPFile>();
        Pattern pattern = Pattern.compile("~.*?~");
        Matcher matcher;
        for (FTPFile file : files) 
        {
            matcher = pattern.matcher(file.getName());
            if(matcher.matches())
            {
                ret.add(file);
            }
        }
        return ret;
    }
    

    由于这个〜某些〜文件被拾取并发送到最终目的地。

    我的问题是:

    1. 从最终目的地发送到ftp位置的文件有不同的模式,我不知道放在哪里(@ something某事物)。
    2. 有时可能会篡改ftp文件夹并删除文件。如果是这样,我想春天重写文件。同一文件将再次写入<ftp:inbound-channel-adapter>中提到的本地目录中。但ftp出站通道适配器不会选择文件并将其放在ftp位置。根据@ Gary的回答,我需要为入站通道适配器配置过滤器以避免接受一次过滤器。
    3. 这是否意味着我应该创建两个单独的通道和两个不同的流程,一个用于后面,一个用于第四个?这是我的要求的正确方法吗?
    4. 感谢您的帮助

      EDIT ::

      我试图实现两个不同的过程。一个用remoteir从模式〜东西〜中获取文件,另一个从本地目录中获取文件@ something @ something。虽然基本功能正常,但如果远程目录中的文件被删除,则无法再次执行第二个流程。正如Gary所说,接受所有过滤器都需要到位,但我不知道如何使用自定义过滤器和接受所有过滤器。

      感谢任何建议

2 个答案:

答案 0 :(得分:0)

默认配置AcceptOnceFileListFilter。使用入站适配器上的local-filter使用其他过滤器(例如AcceptAllFileListFilter)。请参阅the documentation

也就是说,您的应用程序看起来很奇怪 - 看起来您正在提取文件并将其发回。

答案 1 :(得分:0)

这是有效的

我继续使用这两个流并更改了我的bean配置以包含accept all过滤器。

这是现在的配置。

      <bean id="fileNameGenerator" class="com.polling.util.FileNameGenerator"/>   
    <int-file:inbound-channel-adapter id="filesIn" directory="file:${paths.root}" channel="abc" filter="compositeFilter"  >
        <int:poller id="poller" fixed-rate="500" />

    </int-file:inbound-channel-adapter>
    <int:channel id="abc"/>
    <bean id="compositeFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
        <constructor-arg>
            <list>
                <!-- Ensures that the file is whole before processing it -->
                <bean class="com.polling.util.CustomFileFilter"/>
                <!-- Ensures files are picked up only once from the directory -->
                <bean class="org.springframework.integration.file.filters.AcceptOnceFileListFilter" />
            </list>
        </constructor-arg>
    </bean> 

    <int-file:outbound-channel-adapter channel="abc" id="filesOut"
        directory-expression="@outPathBean.getPath()"
        delete-source-files="true" filename-generator="fileNameGenerator" >
        <int-file:request-handler-advice-chain>
         <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload.delete()" />
          </bean>
    </int-file:request-handler-advice-chain>
        </int-file:outbound-channel-adapter>
   <bean id="ftpClientFactory"
    class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
    <property name="host" value="${ftp.ip}"/>
    <property name="port" value="${ftp.port}"/>
    <property name="username" value="${ftp.username}"/>
    <property name="password" value="${ftp.password}"/>
    <property name="clientMode" value="0"/>
    <property name="fileType" value="2"/>
    <property name="bufferSize" value="100000"/>
</bean>

     <int:channel id="ftpChannel1"/> 
 <int-ftp:inbound-channel-adapter id="ftpInbound1"
    channel="ftpChannel1"
    session-factory="ftpClientFactory"
    charset="UTF-8"
    local-directory="file:${paths.root}"
    delete-remote-files="true"
    temporary-file-suffix=".writing"
    remote-directory="."
    preserve-timestamp="true"
     auto-startup="true" 
     local-filter="compositeFilterLocal">
    <int:poller fixed-rate="1000"/>
</int-ftp:inbound-channel-adapter>
  <int-ftp:outbound-channel-adapter id="ftpOutbound1"
    channel="ftpChannel1"
    session-factory="ftpClientFactory"
    charset="UTF-8"
    remote-file-separator="/"
    auto-create-directory="true"
     remote-directory="${file.ftpfolder}" 
    use-temporary-file-name="true"
     temporary-file-suffix=".writing">
    <int-ftp:request-handler-advice-chain>
         <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload.delete()" />
          </bean>
    </int-ftp:request-handler-advice-chain>
</int-ftp:outbound-channel-adapter>



   <int:channel id="ftpChannel"/> 
<int-ftp:inbound-channel-adapter id="ftpInbound"
    channel="ftpChannel"
    session-factory="ftpClientFactory"
    charset="UTF-8"
    local-directory="file:${paths.root}"
    delete-remote-files="true"
    temporary-file-suffix=".writing"
    remote-directory="${file.ftpfolder}"

    filter="compositeFilterRemote"
     preserve-timestamp="true"
     auto-startup="true">
    <int:poller fixed-rate="1000"/>
</int-ftp:inbound-channel-adapter>
<int-ftp:outbound-channel-adapter id="ftpOutbound"
    channel="ftpChannel"
    session-factory="ftpClientFactory"
    charset="UTF-8"
    remote-file-separator="/"
    auto-create-directory="true"
    remote-directory="${file.ftpfolder}" 
    use-temporary-file-name="true"
     temporary-file-suffix=".writing">
    <int-ftp:request-handler-advice-chain>
         <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload.delete()" />
          </bean>
    </int-ftp:request-handler-advice-chain>
  </int-ftp:outbound-channel-adapter>

<bean id="acceptAllFilter" class="org.springframework.integration.file.filters.AcceptAllFileListFilter" />
 <bean id="compositeFilterLocal" class="org.springframework.integration.file.filters.CompositeFileListFilter">
        <constructor-arg>
            <list>
                <!-- Ensures that the file is whole before processing it -->
                <bean class="com.polling.util.CustomFileFilterLocal"/>
                <!-- Ensures files are picked up only once from the directory -->
                <bean class="org.springframework.integration.file.filters.AcceptAllFileListFilter" />
            </list>
        </constructor-arg>
    </bean>
    <bean id="compositeFilterRemote" class="org.springframework.integration.file.filters.CompositeFileListFilter">
        <constructor-arg>
            <list>
                <!-- Ensures that the file is whole before processing it -->
                <bean class="com.polling.util.CustomFileFilterRemote"/>
                <!-- Ensures files are picked up only once from the directory -->
                <bean class="org.springframework.integration.file.filters.AcceptOnceFileListFilter" />
            </list>
        </constructor-arg>
    </bean>

如果有人有任何建议可以提高效率,请告知我们。截至目前我可以反复下载文件。所以继续这个......

由于