Using spring-integration-sftp: 5.1.3
我有一个入站设置,RotatingServerAdvice
正在监视两个目录:
--inbox
-----dir1
-----dir2
观看:inbox/dir1
和inbox/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
然后在处理程序中:
从文件名中提取远程目录:
public String extractRemoteDir(File ackFile) { String fileName = ackFile.getName(); return fileName.split("_")[0].replaceAll("-", "/"); }
- 远程目录上的自定义逻辑
- 删除确认文件
使它不那么黑客化的一件事是知道本地文件处理程序中的远程目录(可能在标头中(,但我没有找到找到它的方法。