Spring integration 如何处理文件转换期间的错误

Spring integration 如何处理文件转换期间的错误,spring-integration,Spring Integration,当一个大文件被上传到一个轮询目录,并试图解压时,会发生一个错误,因为该文件尚未完成 如何在一段时间后重试轮询 @Bean @InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedRate = "1500")) public FileReadingMessageSource poll() { FileReadingMessageSource source = new FileReadingMessageSou

当一个大文件被上传到一个轮询目录,并试图解压时,会发生一个错误,因为该文件尚未完成

如何在一段时间后重试轮询

@Bean
@InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedRate = "1500"))
public FileReadingMessageSource poll() {
    FileReadingMessageSource source = new FileReadingMessageSource();
    source.setScanEachPoll(true);
    source.setDirectory(new File(pathConfig.getIncomingDirPath()));
    source.setUseWatchService(true);
    source.setFilter(new SimplePatternFileListFilter("*.zip"));
    return source;
}

@Transformer(inputChannel = "inputChannel", outputChannel = "unzipChannel")
public Message convert(Message<File> fileMessage) {
    UnZipTransformer unzipTransformer = new UnZipTransformer();
    unzipTransformer.setZipResultType(ZipResultType.FILE);
    unzipTransformer.setWorkDirectory(new File(pathConfig.getWorkDirPath()));
    unzipTransformer.setDeleteFiles(false);
    unzipTransformer.afterPropertiesSet();
    File file = fileMessage.getPayload();
    return unzipTransformer.transform(fileMessage);
}

实际上,由于您只使用了
SimplePatternFileListFilter
,因此在每个轮询间隔都将重试您的任何文件

为避免反复重新获取同一文件(如果在过程结束时未将其删除),建议使用
AcceptOnceFileListFilter
作为
CompositeFileListFilter
的一部分

如果出现类似您的错误,您可以使用
expressionevaluationrequesthandleradvice
调用
onFailureExpression
ResettableFileListFilter.remove()
实现
AcceptOnceFileListFilter

另一方面,而不是<代码> ExpRealStudioReqththand Lead建议,您可以考虑使用<代码> RequestHandlerRetryAdvice <代码>重试<代码>解压缩< /代码>进程:您不需要从LoalStury./P>重新获取文件。 您应该将这些AOP建议应用于

@Transformer

请参阅中的更多信息


顺便说一句,我想说,
fixedRate
不适合大文件。特别是当你有这样的错误时。
fixedDelay
会更好。有关更多信息,请参阅他们的JavaDocs。

通常最好使用不同的名称上载文件,然后在传输完成后重命名(例如,spring集成适配器就是这样做的)。另一种技术是在传输完成时发送第二个文件,并使用过滤器忽略没有标记文件的文件。另一个可能适用于您的选项是
LastModifiedFileListFilter
,只要操作系统在传输过程中更新文件修改日期即可。只有在一段时间没有修改的情况下才接受该文件。非常感谢Artem和Gary!Gary,
LastModifiedFileListFilter
不适用于大文件。我更新了我的代码片段。Artem,我对如何使用SpEL表达式调用
AcceptOnceFileListFilter.remove()
有点困惑。
@AcceptOnceFileListFilter.remove(有效载荷)
,其中
有效载荷
是一个轮询的
文件。您在
@Transformer
@Bean
@InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedDelay = "1500"))
public FileReadingMessageSource poll() {
    FileReadingMessageSource source = new FileReadingMessageSource();
    source.setScanEachPoll(true);
    source.setDirectory(new File(pathConfig.getIncomingDirPath()));
    source.setUseWatchService(true);
    FileListFilter simplePatternFileListFilter = new SimplePatternFileListFilter("*.zip");
    source.setFilter(new ChainFileListFilter<>().addFilter(simplePatternFileListFilter));
    return source;
}

@Transformer(inputChannel = "inputChannel", outputChannel = "unzipChannel", 
  adviceChain = "retryOnIncompleteData")
public Message convertZip(Message<File> fileMessage) {
    UnZipTransformer unzipTransformer = new UnZipTransformer();
    unzipTransformer.setZipResultType(ZipResultType.FILE);
    unzipTransformer.setWorkDirectory(new File(pathConfig.getWorkDirPath()));
    unzipTransformer.setDeleteFiles(false);
    unzipTransformer.afterPropertiesSet();
    return unzipTransformer.transform(fileMessage);
}

@Bean
public Advice retryOnIncompleteData() {
    RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
    RetryTemplate template = createRetryTemplate();
    advice.setRetryTemplate(template);
    return advice;
}

private RetryTemplate createRetryTemplate() {
    RetryTemplate template = new RetryTemplate();
    SimpleRetryPolicy policy = new SimpleRetryPolicy();
    policy.setMaxAttempts(15);
    template.setRetryPolicy(policy);
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(25000l);
    template.setBackOffPolicy(backOffPolicy);
    return template;
}