这是my earlier question关于使用spring集成复制文件的后续内容。
基本流程是递归扫描目录以查找匹配的文件。找到文件后,使用持久性元数据存储来跟踪文件,然后使用@ServiceActivator将文件复制到/ processing文件夹。单独的@InboundChannelAdapter用于扫描此/处理文件夹,然后启动弹出批处理作业。
我面临的问题是,我希望将文件重命名为/ processing文件夹,但我用于DefaultFilenameGenerator的任何表达式都不会出现工作,因为邮件标题只是具有' id'和'时间戳',但我不能引用其中任何一个。
从documentation开始执行默认行为的第二种情况:
- 针对Message评估表达式,如果结果是非空字符串,则将其用作文件名。
- 否则,如果有效负载是java.io.File,请使用文件的文件名。
- 否则,请使用附加.msg的消息ID作为文件名。
醇>
最终,我想使用这样的表达式:
headers['id'] + '_' + headers['file_name']
但我使用的任何内容都会被忽略或出错。下面的代码段会尝试使用标题[' id'],但这会产生一个空字符串(我猜测?),因此第二个默认行为就会出现。
@Bean
@InboundChannelAdapter(channel = "sourceFileChannel", poller = @Poller(fixedRate = "5000", maxMessagesPerPoll = "-1"))
public MessageSource<File> sourceFiles() {
CompositeFileListFilter<File> filters = new CompositeFileListFilter<>();
filters.addFilter(new SimplePatternFileListFilter(filenamePattern));
filters.addFilter(persistentFilter());
FileReadingMessageSource source = new FileReadingMessageSource();
source.setAutoCreateDirectory(true);
source.setDirectory(new File(sourceDirectory));
source.setFilter(filters);
source.setUseWatchService(true);
return source;
}
@Bean
@InboundChannelAdapter(channel = "processingFileChannel", poller = @Poller(fixedRate = "5000", maxMessagesPerPoll = "-1"))
public MessageSource<File> processingFiles() {
CompositeFileListFilter<File> filters = new CompositeFileListFilter<>();
filters.addFilter(new SimplePatternFileListFilter(filenamePattern));
filters.addFilter(new AcceptOnceFileListFilter<>());
FileReadingMessageSource source = new FileReadingMessageSource();
source.setAutoCreateDirectory(true);
source.setDirectory(new File(processingDirectory));
source.setFilter(filters);
return source;
}
@Bean
@ServiceActivator(inputChannel = "sourceFileChannel")
public MessageHandler fileOutboundChannelAdapter() {
FileWritingMessageHandler adapter = new FileWritingMessageHandler(new File(processingDirectory));
adapter.setDeleteSourceFiles(false);
adapter.setAutoCreateDirectory(true);
adapter.setExpectReply(false);
adapter.setFileNameGenerator(defaultFileNameGenerator());
return adapter;
}
@Bean
public DefaultFileNameGenerator defaultFileNameGenerator() {
DefaultFileNameGenerator defaultFileNameGenerator = new DefaultFileNameGenerator();
defaultFileNameGenerator.setHeaderName("id");
//defaultFileNameGenerator.setExpression("headers['id']");
return defaultFileNameGenerator;
}
修改
我使用的解决方法是自己扩展DefaultFileNameGenerator。然而,Artem在评论中正确地展示了如何访问所需的部分。
这是Artem的正确解决方案:
defaultFileNameGenerator.setExpression("headers.id + '_' + payload.name");
以下是解决方法代码:
public class FilenameGenerator extends DefaultFileNameGenerator {
public FilenameGenerator() {
super();
}
@Override
public String generateFileName(Message<?> message) {
return message.getHeaders().getId().toString() + "_" + ((File) message.getPayload()).getName();
}
}
答案 0 :(得分:1)
file_name
后没有FileReadingMessageSource
标头,因此您必须使用payload
:
defaultFileNameGenerator.setExpression("headers.id + '_' + payload.name");