Spring boot 当数据库关闭时,如何将任何下载的文件路由到错误通道,以及在数据库打开后如何处理这些文件?

Spring boot 当数据库关闭时,如何将任何下载的文件路由到错误通道,以及在数据库打开后如何处理这些文件?,spring-boot,spring-integration,Spring Boot,Spring Integration,我已经在我的springboot应用程序中实现了轮询。这段代码定期检查远程目录,并从远程目录下载任何新文件。下载文件后,我们处理文件并将数据保存在数据库中。假设数据库关闭,则处理的文件数据不会保存在数据库中。每当数据库再次打开时,我的文件将被删除未拾取以进行处理,因此文件数据未保存。我在网上了解到,如果我能够将无法在DB中保存数据的文件路由到错误通道,则每当DB启动时,文件都将得到处理 下面是我下载该文件的代码 @Bean 属性配置属性(){ 属性配置=新属性(); config.setProp

我已经在我的springboot应用程序中实现了轮询。这段代码定期检查远程目录,并从远程目录下载任何新文件。下载文件后,我们处理文件并将数据保存在数据库中。假设数据库关闭,则处理的文件数据不会保存在数据库中。每当数据库再次打开时,我的文件将被删除未拾取以进行处理,因此文件数据未保存。我在网上了解到,如果我能够将无法在DB中保存数据的文件路由到错误通道,则每当DB启动时,文件都将得到处理

下面是我下载该文件的代码

@Bean
属性配置属性(){
属性配置=新属性();
config.setProperty(“PreferredAuthentications”、“password”);
返回配置;
}
@Bean(name=PollerMetadata.DEFAULT\u POLLER)
公共PollerMetadata pollRemoteDirectory(){
PollerMetadata PollerMetadata=新PollerMetadata();
pollerMetadata.setTrigger(
新的PeriodicTrigger(getSftpConfig().getPollingInterval(),TimeUnit.MINUTES));
pollerMetadata.setMaxMessagesPerPoll(1000);
返回pollerMetadata;
}
@豆子
SftpInboundFileSynchronizer SyncRemoteFileToLocalDirectory()引发错误的FormedUrlexception{
SftpInboundFileSynchronizer fileSync=新的VsSftpInboundFileSynchronizer(getSftpConfig().sftpSessionFactory());
fileSync.setDeleteRemoteFiles(true);
fileSync.setRemoteDirectory(getSftpConfig().getRemoteFilePath());
CompositeFileListFilter CompositeFileListFilter=新建
CompositeFileListFilter();
addFilter(新的SftpSimplePatternFileListFilter(“*.xml”);
setFilter(compositeFileListFilter);
返回文件同步;
}
@豆子
@内置通道适配器(value=“sftpChannel”)
public MessageSource setMessageSourceAndLocalDirectory()引发格式错误的异常{
SftpInboundFileSynchronizingMessageSource=新的SftpInboundFileSynchronizingMessageSource(
syncRemoteFilesToLocalDirectory());
setLocalDirectory(新文件(getSftpConfig().getArchiveFilePath());
source.setAutoCreateLocalDirectory(true);
返回源;
}
@豆子
@ServiceActivator(inputChannel=“sftpChannel”)
SftpFileHandler messageHandler(){
返回新的SftpFileHandler();
}
@豆子
公共静态资源BundleMessageSource emailMessageSource(){
最终ResourceBundleMessageSource=新ResourceBundleMessageSource();
messageSource.setBasename(“邮件/邮件”);
返回消息源;
}
@豆子
公共静态SpringTemplateEngine emailTemplateEngine(){
最终的SpringTemplateEngine templateEngine=新的SpringTemplateEngine();
addTemplateResolver(textTemplateResolver());
addTemplateResolver(htmlTemplateResolver());
addTemplateResolver(stringTemplateResolver());
setTemplateEngineMessageSource(emailMessageSource());
返回模板引擎;
}

轮询文件存储在
SftpInboundFileSynchronizingMessageSource
的内部
文件系统TempersistentAcceptOnceFileListFilter
中的问题

您需要像这样配置外部bean:

@Bean
public FileSystemPersistentAcceptOnceFileListFilter localFilefilter() {
    return new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpFiles");
}
 source.setLocalFilter(localFilefilter());
然后像这样注入它:

@Bean
public FileSystemPersistentAcceptOnceFileListFilter localFilefilter() {
    return new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpFiles");
}
 source.setLocalFilter(localFilefilter());
当存储到DB中的文件发生异常时,您只需使用无法存储的文件调用该过滤器的
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);

}
/**
*一个{@link FileListFilter},可以通过从其目录中删除特定文件来重置它
*国家。
*@作者加里·拉塞尔
*@自4.1.7起
*
*/
公共接口ResettableFileListFilter扩展FileListFilter{
/**
*从筛选器中删除指定的文件,以便下次尝试时将其传递。
*@param f要删除的元素。
*@如果此调用导致文件被删除,则返回true。
*/
布尔删除(F);
}
我可能猜您的
SftpFileHandler
完成了这项艰巨的工作,因此您可以为其
@ServiceActivator
配置一个
adviceChain
,使用
expressionEvaluationRequestHandleradvice
,并配置其
failureChannel
以执行所述的
delete()
操作

这样,将在下一个轮询周期再次从SFTP轮询未处理的文件

实现该目标的另一种方法是使用重试。为此,您可以使用
RequestHandlerRetryAdvice
作为相同的
@ServiceActivator.adviceChain()
原因。在这种情况下,相同的文件将一次又一次地尝试存储在DB中,而不需要任何必需的错误处理逻辑


请参阅参考手册中的更多信息:

为@ServiceActivator配置带有表达式EvaluationRequestHandlerAdvice的adviceChain,并将其failureChannel配置为执行上述删除()操作---这种方法需要IntegrationFlow,对吗?还有其他方法可以避免IntegrationFlow吗?没有。只有足够的
@ServiceActivator
用于该
故障通道