You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Camel 2.16.5:聚合后拆分Exchange写入文件系统异常排查

问题排查与修复方案

我仔细看了你的代码,发现几个关键问题导致输出目录没有生成文件,下面逐一分析并给出修复方案:

1. 路由添加时机错误,核心路由未启动

你的Main类里犯了一个常见错误:先启动CamelContext,再添加AggregatorRoute和FileWriter路由。在Apache Camel 2.x版本中,上下文启动后新增的路由不会自动激活,这意味着负责监听input目录、聚合文件的路由,以及写文件的路由根本没在运行,自然无法处理后续逻辑。

修复方法:必须在启动CamelContext之前,把所有需要的路由都添加进去。

2. 聚合后的拆分逻辑错误,无法获取文件内容

你用GroupedExchangeAggregationStrategy聚合3个文件后,Exchange的Body是一个List<Exchange>(每个元素对应一个输入文件的Exchange实例)。直接调用split(body())会把每个Exchange当作拆分元素,后续${body}会输出Exchange对象的字符串形式(比如org.apache.camel.impl.DefaultExchange@xxxx),而不是你需要的文件内容,这也会导致写文件逻辑异常。

修复方法:拆分时需要提取每个Exchange中的实际文件内容,用setBody(simple("${body.in.body}"))来获取每个聚合项的Body。

3. 可选优化:文件读取的锁机制

StringRoute写入文件时,file:input组件可能会在文件还没完全写入(或处于锁定状态)时尝试读取,导致读取失败。可以给file组件加上readLock=changed参数,确保文件写完且内容稳定后再读取。


修正后的完整代码

StringRoute(保持原有逻辑即可)

import org.apache.camel.builder.RouteBuilder;

public class StringRoute extends RouteBuilder {
    public void configure() throws Exception {
        from("direct:readStrings")
                .split(body())
                .to("file:input?fileExist=Append&fileName=${body}.txt");
    }
}

AggregatorRoute(修复拆分逻辑)

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy;

public class AggregatorRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("file:input?readLock=changed")
                .aggregate(new GroupedExchangeAggregationStrategy())
                .constant(true)
                .completionSize(3)
                // 拆分聚合后的Exchange列表,提取每个Exchange的Body内容
                .split(body())
                .setBody(simple("${body.in.body}"))
                .to("direct:writeFiles");
    }
}

FileWriter(简化后保留核心逻辑)

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.Processor;
import org.apache.camel.Exchange;

public class FileWriter extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("direct:writeFiles")
                .process(new Processor() {
                    @Override
                    public void process(Exchange exchange) throws Exception {
                        System.out.println("In FileWriter: " + exchange.getIn().getBody());
                    }
                })
                .to("file:output?fileName=${body}.txt");
    }
}

Main类(修复路由添加顺序)

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.impl.DefaultCamelContext;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        CamelContext camelContext = new DefaultCamelContext();
        try {
            // 先添加所有路由,再启动上下文
            camelContext.addRoutes(new StringRoute());
            camelContext.addRoutes(new AggregatorRoute());
            camelContext.addRoutes(new FileWriter());
            
            camelContext.start();
            ProducerTemplate producerTemplate = camelContext.createProducerTemplate();
            
            List<String> list = new ArrayList<String>();
            String a = "abc";
            String b = "cdb";
            String c = "efg";
            list.add(a);
            list.add(b);
            list.add(c);
            
            producerTemplate.sendBody("direct:readStrings", list);
            
            // 延长等待时间,确保文件处理全流程完成
            Thread.sleep(15000);
            camelContext.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

验证步骤

  1. 确保项目根目录下存在input和output文件夹(Camel会自动创建,但手动创建更稳妥)
  2. 运行Main类,控制台会输出In FileWriter: abc、In FileWriter: cdb、In FileWriter: efg的日志
  3. 打开output目录,就能看到生成的三个txt文件了

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:18:21