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

Apache Camel中CSV转换场景下动态创建List及获取Exchange记录数的问题

这个问题我太熟悉了!Apache Camel的CSV组件有个小坑:当CSV文件只有一行数据(除了表头)时,它不会自动把单个Wehicle对象包装成List<Wehicle>,而是直接返回单个对象实例;但有多行时才会返回List。这就是你强转List<Wehicle>失败的核心原因。

下面逐个解决你的疑问:

1. 动态创建List处理单个/多个对象

你可以通过判断消息体的实际类型来统一处理,把单个对象也包装成List:

public void process(Exchange exchange) throws Exception {
    List<Cars> output = new ArrayList<>();
    Object body = exchange.getIn().getBody();
    List<Wehicle> rows;

    // 判断body类型,统一转成List格式
    if (body instanceof Wehicle) {
        // 单个对象,包装成List
        rows = new ArrayList<>();
        rows.add((Wehicle) body);
    } else if (body instanceof Collection) {
        // 多个对象,直接转换为ArrayList
        rows = new ArrayList<>((Collection<? extends Wehicle>) body);
    } else {
        // 处理异常情况,比如空body或非预期类型
        throw new IllegalArgumentException("无法解析消息体,类型为: " + (body != null ? body.getClass().getName() : "null"));
    }

    // 后续转换逻辑保持不变
    for (Wehicle row : rows) {
        output.add(new Cars(row));
    }
    exchange.getIn().setBody(output);
    exchange.getIn().setHeader("CamelOverruleFileName", "CarEntries.csv");
}

2. 获取消息中的记录数量

有了上面统一的rows List之后,直接调用rows.size()就能拿到记录数。如果不想先转成List,也可以直接通过类型判断计算:

Object body = exchange.getIn().getBody();
int recordCount;
if (body instanceof Wehicle) {
    recordCount = 1;
} else if (body instanceof Collection) {
    recordCount = ((Collection<?>) body).size();
} else {
    recordCount = 0; // 空body或非预期类型,按0条记录处理
}

3. 其他实现方式

除了在Processor里处理,你还可以在Camel路由层面配置CSV组件,强制它始终返回List,不管记录数量多少。

比如使用CsvDataFormat并设置useList=true:

// 配置CSV数据格式,和你的注解配置保持一致
CsvDataFormat csvFormat = new CsvDataFormat();
csvFormat.setUnmarshalType(Wehicle.class);
csvFormat.setSkipFirstLine(true);
csvFormat.setSeparator(',');
csvFormat.setCrlf("UNIX");
csvFormat.setUseList(true); // 关键配置:强制返回List格式

// 在路由中使用该格式
from("你的输入端点")
    .unmarshal(csvFormat)
    .to("direct:consume")
    .process(你的Processor实例);

这样配置后,不管CSV是单行还是多行,exchange.getIn().getBody()都会返回List<Wehicle>,你就不用在Processor里做类型判断了,直接强转即可。

另外,也可以利用Camel的TypeConverter特性,直接用exchange.getIn().getBody(List.class)来安全转换,不过需要确保你的Camel版本支持单个对象到List的自动转换(大部分新版本都支持,但路由配置的方式更稳妥)。

最后小提醒:记得处理空文件或者表头后无数据的情况,加个空值判断避免NullPointerException哦!

内容的提问来源于stack exchange,提问作者Szilágyi István

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:47:48