Apache Camel拆分List<Object>失败,仅输出f1未输出f2求排查
你遇到的问题核心在于拆分List<TestPOJO>时使用了错误的split表达式,导致Camel没有正确遍历整个集合,只处理了第一个元素。
为什么会出现这个问题?
看你的代码,第一个路由里用了split(body(TestPOJO.class)):
.split(body(TestPOJO.class)).to("stream:out");
这里的body(TestPOJO.class)并不是告诉Camel要拆分出TestPOJO类型的元素,而是尝试将整个消息体(也就是你放入的List<TestPOJO>)转换为TestPOJO类型。Camel的类型转换器在处理集合转单个对象时,默认会取集合的第一个元素作为转换结果——这就是为什么你只看到f1被输出,而f2完全没被处理。
而第二个路由里的split(body(String.class))能正常输出,其实是个“巧合”:Camel的类型转换器把List<String>转换成了一个用逗号分隔的字符串(比如"s1,s2"),然后split默认按逗号拆分这个字符串,刚好得到了s1和s2。但这并不是正确的集合拆分方式,属于依赖了类型转换器的隐式行为,非常不推荐。
正确的写法
要正确拆分List中的每个元素,不管元素是String还是自定义POJO,都应该直接使用split(body())——因为body()会返回整个List集合,Camel会自动遍历拆分其中的每个元素:
修改第一个路由的split部分:
.from("timer:simpleTimer1?period=2000") .process((exchange) -> { List<TestPOJO> names = new ArrayList<>(); names.add(new TestPOJO("f1")); names.add(new TestPOJO("f2")); exchange.getOut().setBody(names); }) .split(body()) // 直接拆分消息体中的List .to("stream:out");
同时,建议把第二个路由的split也改成split(body()),避免依赖隐式类型转换的不确定行为:
.from("timer:simpleTimer2?period=2000") .process((exchange) -> { List<String> names = new ArrayList<>(); names.add("s1"); names.add("s2"); exchange.getOut().setBody(names); }) .split(body()) // 同样直接拆分List .to("stream:out");
额外说明
如果你需要明确指定拆分后元素的类型(比如做类型校验),可以在split后加上.type()方法:
.split(body()).type(TestPOJO.class)
这样Camel会确保拆分出的每个元素都是TestPOJO类型,否则会抛出类型转换异常,比隐式转换更安全。
修改后,两个路由都会正确遍历集合中的所有元素,输出应该是s1 s2 f1 f2 s1 s2 f1 f2这样的结果。
内容的提问来源于stack exchange,提问作者Jericho

