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
相关产品推荐
相关产品推荐

