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