2014-12-02 42 views
0

我在我的应用程序中有以下配置。我正在写一个文件到ftp文件夹并从ftp位置读取。ftp出站通道适配器不传输相同的文件

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

这是配置:

<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的回答,我添加了一个CustomFilter到FTP入境信道滤波器属性。这将检查文件名的正则表达式,如下所示:

@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; 
} 

由于这个东西,文件被拾取并发送到最终目的地。

我的问题是:从最终目的地发送到FTP位置

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

感谢您的帮助

编辑::

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

任何建议都理解

回答

0

这是什么工作

我继续与二而改变了我的bean的配置,包括接受所有过滤器。

这是现在的配置。

 <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> 

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

谢谢

0

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

这就是说,你的应用程序看起来很奇怪 - 看起来你正在获取文件并简单地发回它们。

+0

它是一个文件服务器。将文件从ftp更改为通用文件,复制到文件服务器。当请求下载服务器上的定位文件时,将其放在由ftp频道选取的本地文件夹中。希望有道理 – kavita 2014-12-04 04:59:18

+0

这涉及到出站适配器不呢?从本地目录获取到ftp文件夹的文件是出站适配器的工作权利? – kavita 2014-12-04 05:08:32

+0

否;入站获取文件,然后通过消息发送给'ftpChannel'(如果它通过'local-filter')。但是,'ftpChannel'是在出站适配器上配置的通道。这就是为什么你的应用程序看起来很奇怪 - 获取一个远程文件并将其发回。 – 2014-12-04 13:55:35

相关问题