Camel ZipAggregationStrategy动态归档文件未输出到指定目录问题
问题原因及解决方案
核心原因
第二个示例的问题出在 completionFromBatchConsumer() 的使用场景不匹配:
- 第一个示例中,
file:input/directory是Camel的批量消费者(Batch Consumer),它会自动在Exchange中填充CamelBatchSize、CamelBatchIndex等批量消费相关头信息,completionFromBatchConsumer()能依靠这些信息准确判断聚合完成时机。 - 第二个示例用
direct:zip启动流程,直接将File[]设为消息体,此时split是基于普通数组迭代,Exchange中无批量消费头信息,completionFromBatchConsumer()无法识别聚合完成的触发条件。
你看到temp目录有正确的zip包,是ZipAggregationStrategy内部为临时存储聚合中的zip内容生成的文件,但因聚合未触发正式完成逻辑,所以不会将临时文件同步到指定的output/directory目录。
解决方案
有两种可行的修复方式:
方案1:改用completionSize()指定聚合完成条件
在Processor中获取文件数组长度并设置到Exchange属性,通过completionSize()明确聚合完成的数量:
from("direct:zip") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { File srcFile = new File("path-to-target-folder"); File[] files = srcFile.listFiles(); exchange.getIn().setBody(files); // 设置批量大小属性 exchange.setProperty(Exchange.BATCH_SIZE, files.length); } }) .split(body()) .aggregate(constant(true), new ZipAggregationStrategy()) // 用completionSize替代completionFromBatchConsumer .completionSize(exchangeProperty(Exchange.BATCH_SIZE)) .eagerCheckCompletion() .setHeader(Exchange.FILE_NAME, constant("reports-2.zip")) .to("file:output/directory");
方案2:使用file组件动态路径配置
若目标目录是运行时确定的,可直接用file组件的动态路径表达式,保留批量消费者特性:
from("direct:zip") .process(exchange -> { // 运行时获取目标目录路径 String targetDir = "path-to-target-folder"; exchange.setProperty("targetDir", targetDir); }) // 用表达式动态指定file消费者路径 .toD("file:${exchangeProperty.targetDir}?noop=true") .split(body()) .aggregate(constant(true), new ZipAggregationStrategy()) .completionFromBatchConsumer() .eagerCheckCompletion() .setHeader(Exchange.FILE_NAME, constant("reports-2.zip")) .to("file:output/directory");
额外说明
completionFromBatchConsumer()仅适用于Camel内置的批量消费者组件(如file、ftp等),这类组件会自动维护批量消费元数据。- 手动处理集合/数组的
split时,必须显式指定聚合完成条件(如completionSize、completionTimeout等),否则聚合逻辑会持续等待,无法触发最终输出。
内容的提问来源于stack exchange,提问作者Lazy
相关产品推荐
相关产品推荐

