Spring SFTP 适配器入站适配器与旋转服务器建议 - 获取完整路径



Using spring-integration-sftp: 5.1.3

我有一个入站设置,RotatingServerAdvice正在监视两个目录:

--inbox
-----dir1
-----dir2

观看:inbox/dir1inbox/dir2

本地目录:temp/sftp

当我将文件放入inbox/dir1/file1.txt时,我的处理程序按预期调用,file1.txt被复制到temp/sftp/file1.txt(<- 这是问题所在,详细信息如下(

问题:

我的用例是,当我获取文件时,我想知道它来自哪个远程子目录。如果本地文件被传输到temp/sftp/inbox/dir1/file1.txt那么我可以判断它来自/inbox/dir1,我可以在这个目录上的远程 sftp 上执行一些操作。

为什么文件是平面传输的,而不是在本地目录的子目录中?任何帮助将不胜感激。

入站适配器:

@Bean
public IntegrationFlow sftpInboundsFlow(DelegatingSessionFactory<LsEntry> delegatingSessionFactory,
SftpServiceActivator serviceActivator) throws JSchException {
SftpConnection config = sftpConnectionConfig.getSftpConnectionConfig(delegatingSessionFactory);
return IntegrationFlows
.from(Sftp.inboundAdapter(delegatingSessionFactory)
.preserveTimestamp(true)
.autoCreateLocalDirectory(true)
.preserveTimestamp(true)
.remoteDirectory("*")
.filter(new CopartFileFilter(Pattern.compile(".*")))
.localDirectory(new File( System.getProperty("java.io.tmpdir") + "/" + config.getLocalDirectory())),
e -> e.id("inboundSftpChannel")
.autoStartup(true)
.poller(Pollers
.fixedDelay(config.getPollerInterval())
.advice(advice(delegatingSessionFactory))
.maxMessagesPerPoll(1)))
.handle(m -> serviceActivator.handleMessage(m))
.get();
}

处理程序上的文件信息:

file: file1.txt, parent: /var/folders/sd/5k6jwzgs2hj2q165b6x9pql55mp8t7/T/sftp, headers {file_originalFile=/var/folders/sd/5k6jwzgs2hj2q165b6x9pql55mp8t7/T/sftp/file1.txt, id=d2620539-ab0d-2590-9b51-f4dfb442a74a, file_name=file1.txt, file_relativePath=file1.txt, timestamp=1581371879819}

尝试 1:

我认为这与提到的第一种方法相似。

.localFilenameExpression("#remoteDirectory + '/' + #this")

它正确地将文件放在temp/sftp/inbox/dir1/file1.txt.现在的问题是我收到的消息是针对此目录的:

temp/sftp/inbox

不是file1.txt

这样的事情应该可以工作...

子类StandardRotationPolicy,覆盖

@Override
public void beforeReceive(MessageSource<?> source) {
...
}

调用super.beforeReceive(source)然后将源转换为AbstractInboundFileSynchronizingMessageSource<?>

然后拨打getCurrent()以获取当前KeyDirectory

然后abstractInboundFileSynchronizingMessageSource.setLocalDirectory(new File(...));

将自定义实现添加到建议中。

但是,您必须在消息源中使用RecursiveDirectoryScanner,以便扫描树。

或者,使用配置为每次都使用备用目录(或仅在递归模式下inbox(使用 MGET 命令的出站网关。可以将网关配置为重新创建远程树。

由于我是新手,因此在实施建议的解决方案时遇到了一些麻烦。我采用了不同的方法,因为它可以很好地满足我的要求:

sftpInboundsFlow

.localFilenameExpression("#remoteDirectory.replaceAll('/', '-') + '_' + #this")

这会将文件放在本地临时目录中的平面结构中。

temp/sftp:
inbox-dir1_file1.txt

然后在处理程序中:

  1. 从文件名中提取远程目录:

    public String extractRemoteDir(File ackFile) {
    String fileName = ackFile.getName();
    return fileName.split("_")[0].replaceAll("-", "/");
    }
    
  2. 远程目录上的自定义逻辑
  3. 删除确认文件

使它不那么黑客化的一件事是知道本地文件处理程序中的远程目录(可能在标头中(,但我没有找到找到它的方法。

最新更新