我已经在springboot应用程序中实现了轮询。这段代码定期检查远程目录并从远程目录下载任何新文件。下载文件后,我们处理该文件并将数据保存在数据库中。假设数据库已关闭我处理过的文件数据没有保存在DB中。每当DB重新启动时,我的文件都没有被处理,因此文件数据也没有保存。我在网上读到,如果我能够路由其数据无法发送的文件将其保存到DB的错误通道中,则每当DB启动时,文件都会得到处理
下面是我下载文件的代码
@Bean
Properties configProperties(){
Properties config = new Properties();
config.setProperty("PreferredAuthentications", "password");
return config;
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata pollRemoteDirectory() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(
new PeriodicTrigger(getSftpConfig().getPollingInterval(), TimeUnit.MINUTES));
pollerMetadata.setMaxMessagesPerPoll(1000);
return pollerMetadata;
}
@Bean
SftpInboundFileSynchronizer syncRemoteFilesToLocalDirectory() throws MalformedURLException {
SftpInboundFileSynchronizer fileSync = new VsSftpInboundFileSynchronizer(getSftpConfig().sftpSessionFactory());
fileSync.setDeleteRemoteFiles(true);
fileSync.setRemoteDirectory(getSftpConfig().getRemoteFilePath());
CompositeFileListFilter<ChannelSftp.LsEntry> compositeFileListFilter = new
CompositeFileListFilter<ChannelSftp.LsEntry>();
compositeFileListFilter.addFilter(new SftpSimplePatternFileListFilter("*.xml"));
fileSync.setFilter(compositeFileListFilter);
return fileSync;
}
@Bean
@InboundChannelAdapter(value = "sftpChannel")
public MessageSource setMessageSourceAndLocalDirectory() throws MalformedURLException {
SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
syncRemoteFilesToLocalDirectory());
source.setLocalDirectory(new File(getSftpConfig().getArchiveFilePath()));
source.setAutoCreateLocalDirectory(true);
return source;
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
SftpFileHandler messageHandler() {
return new SftpFileHandler();
}
@Bean
public static ResourceBundleMessageSource emailMessageSource() {
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("mail/MailMessages");
return messageSource;
}
@Bean
public static SpringTemplateEngine emailTemplateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(textTemplateResolver());
templateEngine.addTemplateResolver(htmlTemplateResolver());
templateEngine.addTemplateResolver(stringTemplateResolver());
templateEngine.setTemplateEngineMessageSource(emailMessageSource());
return templateEngine;
}
答案 0 :(得分:1)
已将轮询文件存储在q()
的内部qq()
中的问题。
您需要像这样配置外部bean:
FileSystemPersistentAcceptOnceFileListFilter
然后像这样注入它:
SftpInboundFileSynchronizingMessageSource
当存储在数据库中的文件发生异常时,您只需要使用无法存储的文件调用该过滤器的@Bean
public FileSystemPersistentAcceptOnceFileListFilter localFilefilter() {
return new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpFiles");
}
方法即可。参见 source.setLocalFilter(localFilefilter());
:
delete()
我可能会猜测您的ResettableFileListFilter
会做得很辛苦,因此您可以为/**
* A {@link FileListFilter} that can be reset by removing a specific file from its
* state.
* @author Gary Russell
* @since 4.1.7
*
*/
public interface ResettableFileListFilter<F> extends FileListFilter<F> {
/**
* Remove the specified file from the filter so it will pass on the next attempt.
* @param f the element to remove.
* @return true if the file was removed as a result of this call.
*/
boolean remove(F f);
}
的{{1}}和SftpFileHandler
配置adviceChain
执行上述的@ServiceActivator
操作。
这样,将在下一个轮询周期再次从SFTP轮询未处理的文件。
达成目标的另一种方法是使用 retry 。为此,您可以出于相同的ExpressionEvaluatingRequestHandlerAdvice
原因使用failureChannel
。在这种情况下,相同的文件将尝试一次又一次地存储在DB中,而没有任何必需的错误处理逻辑。
在参考手册:https://docs.spring.io/spring-integration/reference/html/#message-handler-advice-chain和https://docs.spring.io/spring-integration/reference/html/#recovering-from-failures-2
中查看更多信息。