使用Apache Camel Java DSL+BeanIO编组数据对象生成空文件问题
我们的遗留系统基于Apache Camel XML DSL结合BeanIO格式化库,可正常将SQL表数据生成的数据对象编组为文件。新系统切换到Apache Camel 4.0.0、Spring 4.0.0和BeanIO 3.4.0后,改用Java DSL实现相同逻辑,却出现生成文件为空的问题。已确认数据对象及字段均非空,怀疑路由编组写法存在问题,现求助排查原因。旧系统在<camelContext>中定义数据格式并通过ID引用,当前写法看似正确。
路由代码
BeanIODataFormat dataFormat = new BeanIODataFormat("path/beanioFormats/beanio_format.xml", "FormatSourceName"); from("{{cron.process}}") .log(LoggingLevel.INFO, "Creating File") .transform().method("fileGeneratorClass", "generatorMethod") .to("direct:marshalFile") .end(); from("direct:marshalFile") .marshal(dataFormat) .to("file:{{output.file.path}}") .end();
BeanIO格式文件
<?xml version="1.0" encoding="UTF-8"?> <beanio xmlns="http://www.beanio.org/2012/03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd"> <stream name="FormatSourceName" format="fixedlength"> <group name="fileWrapperObject" class="path.to.wrapper.class"> <record name="fileHeader" class="path.to.header.class" minOccurs="1" maxOccurs="1"> <field name="fileRecordIdentifier" rid="true" length="3" required="true" literal="000"/> </record> ... etc
数据对象设置代码
public void generatorMethod(Exchange exchange) { FileWrapperObject fileWrapperObject = new FileWrapperObject(); // fill it with data LOG.info("Wrapper object created"); exchange.getIn().setBody(wrapper); String fileName = "fileName"; exchange.getIn().setHeader(Exchange.FILE_NAME, fileName); }
排查建议
修正
transform方法的使用方式:transform().method()要求方法返回值作为新的Exchange Body,但你的generatorMethod是void类型,直接操作Exchange的In Body会导致transform未正确传递数据。建议改用.bean()替代,因为.bean()支持直接操作Exchange而无需返回值:from("{{cron.process}}") .log(LoggingLevel.INFO, "Creating File") .bean("fileGeneratorClass", "generatorMethod") .to("direct:marshalFile") .end();或者修改方法返回
FileWrapperObject,保留transform用法:public FileWrapperObject generatorMethod(Exchange exchange) { FileWrapperObject fileWrapperObject = new FileWrapperObject(); // fill it with data LOG.info("Wrapper object created"); exchange.getIn().setHeader(Exchange.FILE_NAME, "fileName"); return fileWrapperObject; }验证BeanIO配置文件路径:Camel 4中资源加载逻辑可能有变化,建议给配置路径加上
classpath:前缀,确保文件能被正确加载:BeanIODataFormat dataFormat = new BeanIODataFormat("classpath:path/beanioFormats/beanio_format.xml", "FormatSourceName");开启调试日志:添加
org.apache.camel.component.beanio和org.apache.camel.processor.MarshalProcessor的DEBUG级别日志,查看编组过程中是否有异常或数据丢失的细节。检查BeanIO 3兼容性:BeanIO 3相对于旧版本有API调整,确认数据对象类与配置文件中的映射完全匹配(字段名、类路径、group/record嵌套关系);另外可尝试在
<stream>标签中显式配置换行符,比如lineSeparator="unix",避免格式输出异常。
内容的提问来源于stack exchange,提问作者p23he

