如何在文件转换期间处理错误

时间:2018-02-26 15:46:32

标签: spring-integration

当将大文件上载到轮询目录并尝试解压缩时,会发生错误,因为该文件尚未完成。

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

@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);
}

编辑 - 我无法让LastModifiedFileListFilter使用大文件。它适用于小型的;当我上传一个大的,它不会再做出反应。

EDIT2 感谢 Artem和Gary 的建议,这里有适合我的解决方案。

@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;
}

1 个答案:

答案 0 :(得分:1)

好吧,实际上因为你只使用SimplePatternFileListFilter,所以你的文件将在每个轮询间隔重试。

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

如果出现与您类似的错误,您可以使用ExpressionEvaluatingRequestHandlerAdvice致电onFailureExpression ResettableFileListFilter.remove() AcceptOnceFileListFilter来实施。{/ p>

另一方面,您可以考虑使用ExpressionEvaluatingRequestHandlerAdvice而不是RequestHandlerRetryAdvice来重试unzipping进程:您不需要从本地系统重新获取文件。

这些AOP建议您应该适用于@Transformer

查看Reference Manual中的更多信息。

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