2017-02-02 145 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

相关问题