2017-02-02 92 views
2

我使用Spring集成的DSL SFTP出境用delete

  • Sprint整合(文件,SFTP等)4.3.6
  • 春季啓動1.4.3
  • Spring集成的Java DSL 1.1。 4

我試圖設置一個SFTP出站適配器,該適配器允許我將文件移動到遠程系統上的目錄,並刪除或重命名本地系統中的文件。

所以,舉例來說,我想將一個文件,A.TXT,在本地目錄,並將它在目錄入境 SFTP'ed到遠程服務器。一旦傳輸完成,我希望刪除或重命名本地副本a.txt

我正在爲此嘗試幾種方法。所以這裏是我測試的常見SessionFactory。

protected SessionFactory<ChannelSftp.LsEntry> buildSftpSessionFactory() { 
    DefaultSftpSessionFactory sessionFactory = new DefaultSftpSessionFactory(); 
    sessionFactory.setHost("localhost"); 
    sessionFactory.setUser("user"); 
    sessionFactory.setAllowUnknownKeys(true); 
    sessionFactory.setPassword("pass"); 
    CachingSessionFactory<ChannelSftp.LsEntry> cachingSessionFactory = new CachingSessionFactory<>(sessionFactory, 1); 
    return cachingSessionFactory; 
} 

這是一個變壓器,我有一些頭添加到消息

@Override 
public Message<File> transform(Message<File> source) { 
    System.out.println("here is the thing : "+source); 
    File file = (File)source.getPayload(); 
    Message<File> transformedMessage = MessageBuilder.withPayload(file) 
      .copyHeaders(source.getHeaders()) 
      .setHeaderIfAbsent(FileHeaders.ORIGINAL_FILE, file) 
      .setHeaderIfAbsent(FileHeaders.FILENAME, file.getName()) 
      .build(); 
    return transformedMessage; 
} 

然後我有一個使用輪詢收看的本地目錄中調用這個集成信息流:

@Bean 
public IntegrationFlow pushTheFile(){ 
    return IntegrationFlows 
      .from(s -> s.file(new File(DIR_TO_WATCH)) 
          .patternFilter("*.txt").preventDuplicates(), 
        e -> e.poller(Pollers.fixedDelay(100))) 
      .transform(outboundTransformer) 
      .handle(Sftp.outboundAdapter(this.buildSftpSessionFactory()) 
        .remoteFileSeparator("/") 
        .useTemporaryFileName(false) 
        .remoteDirectory("inbound/") 
      ) 
      .get(); 
} 

這工作正常,但留下本地文件。有關如何在上傳完成後刪除本地文件的任何想法?我應該看看SftpOutboundGateway而不是?

在此先感謝!

Artem的答案完美無缺!這是一個快速示例,它在推送後刪除本地文件。

@Bean 
public IntegrationFlow pushTheFile(){ 
    return IntegrationFlows 
      .from(s -> s.file(new File(DIR_TO_WATCH)) 
          .patternFilter("*.txt").preventDuplicates(), 
        e -> e.poller(Pollers.fixedDelay(100))) 
      .transform(outboundTransformer) 
      .handle(Sftp.outboundAdapter(this.buildSftpSessionFactory()) 
        .remoteFileSeparator("/") 
        .useTemporaryFileName(false) 
        .remoteDirectory("inbound/"), c -> c.advice(expressionAdvice(c)) 
      ) 
      .get(); 
} 

@Bean 
public Advice expressionAdvice(GenericEndpointSpec<FileTransferringMessageHandler<ChannelSftp.LsEntry>> c) { 
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice(); 
    advice.setOnSuccessExpression("payload.delete()"); 
    advice.setOnFailureExpression("payload + ' failed to upload'"); 
    advice.setTrapException(true); 
    return advice; 
} 
+0

可能,這將幫助你 - HTTP://堆棧溢出。com/questions/36247467/spring-sftp-inbound-chanel-adapter -delete-local-file?rq = 1 –

回答

1

爲此,您可以使用多種方法。

所有這些都是基於您對Sftp.outboundAdapter()的原始請求消息採取其他措施的事實。

  1. .publishSubscribeChannel()允許您發送相同的消息給幾個用戶,當第二會收到它只有第一個完成其工作。默認情況下,如果您未指定Executor

  2. routeToRecipients()允許您通過不同的組件獲得相同的結果。

  3. ExpressionEvaluatingRequestHandlerAdvice - 添加此一到Sftp.outboundAdapter()端點定義的.advice() - 第二.handle()參數和執行file.delete()通過onSuccessExpression

    .transform((Integer p) -> p * 2, c -> c.advice(this.expressionAdvice())) 
    
+0

謝謝Artem的迴應。我試圖用你提到的第三個選項來運行,但我有點困惑。 'Sftp.outboundAdapter()'似乎沒有'advice()'方法。我確信我只是想念一件簡單的事情,但你能幫我指出一個方向嗎? – Tristan

+0

確實,您必須看看'.handle()'的'Consumer' arg:https://github.com/spring-projects/spring-integration-java-dsl/wiki/Spring-Integration- Java-DSL-Reference#endpointConfig –

+0

我明白你現在在說什麼。一旦我清理完了,我會發佈一個例子。再次感謝!! – Tristan

相關問題