使用Apache Camel Spring生成CSV文件时遇类型转换错误
嘿,看你的错误信息就知道问题出在哪了:No type converter available to convert from type: com.test.TestBean to the required type: java.util.List... —— 这说明Camel当前处理的消息体是单个TestBean对象,而不是你以为的List<TestBean>,所以<convertBodyTo type="java.util.List"/>才会报错,它没法直接把单个POJO转成List。
我给你几个实用的排查和解决方向:
1. 先确认消息体的真实类型
别光凭自己的代码逻辑想当然,先在路由里加个日志,看看实际的消息体是什么:
<log message="当前消息体类型: ${body.class}, 内容: ${body}" loggingLevel="INFO"/>
如果日志输出显示是单个TestBean,那你得回头查上游代码——是不是某个DAO或者服务方法写错了,本来该返回List<TestBean>,结果返回了单个TestBean?这种低级错误很容易犯。
2. 把单个对象包装成List(如果确实有这种场景)
如果你的业务逻辑里确实存在“有时候返回单个对象,有时候返回List”的情况,那可以用两种方式把单个TestBean包装成List:
方式一:自定义工具Bean
写个简单的包装类:
public class TestBeanListWrapper { public List<TestBean> wrap(Object body) { List<TestBean> resultList = new ArrayList<>(); if (body instanceof List) { resultList.addAll((List<TestBean>) body); } else if (body instanceof TestBean) { resultList.add((TestBean) body); } return resultList; } }
然后在路由里调用这个Bean:
<bean id="testBeanWrapper" class="com.test.TestBeanListWrapper"/> <to uri="bean:testBeanWrapper?method=wrap"/>
方式二:用Camel Simple表达式快速处理
如果场景简单,也可以直接用Simple表达式搞定,不用写额外的Bean:
<setBody> <simple>${body} is 'java.util.List' ? ${body} : Arrays.asList(${body})</simple> </setBody>
3. 直接用Camel的CSV组件(推荐)
其实Camel本身就有专门的CSV组件(camel-csv),能直接把List<TestBean>转成CSV,根本不用手动折腾类型转换。
首先确保你的依赖里引入了它:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-csv</artifactId> <version>你的Camel版本号</version> </dependency>
然后在路由里用marshal生成CSV就行,还能指定表头:
<marshal> <csv> <header>name,tumber,batchId,Type,c_count,Count,amount</header> </csv> </marshal>
这个组件会自动识别List里的TestBean,把每个字段对应到CSV的列中,省心多了。
4. 检查路由的执行顺序
如果上游逻辑确实返回的是List,那你得检查路由里的其他处理器——有没有在<convertBodyTo>之前,用<setBody>或者其他Bean把List中的某个元素取出来了?比如不小心写了${body[0]}这种表达式,把单个对象当成了消息体。
总结一下:先确认消息体的真实类型,要么修正上游返回值,要么把单个对象包装成List,最后用Camel自带的CSV组件来生成文件,这是最稳妥的方案。
内容的提问来源于stack exchange,提问作者nik

