如何使用Apache Camel路由将同一份CSV文件保存到两个不同路径?现有路由报错求助
我来帮你解决这个问题——你猜的没错,问题确实出在Exchange的消息体在第一次toD调用后已经被消费掉了,导致后续的to组件找不到要写入的文件内容。下面给你几个可行的解决方案:
方案1:使用Multicast组件并行发送到两个目的地
Multicast可以把同一个Exchange复制多份,分别发送到不同的端点,这样每个端点都能拿到完整的文件内容,是处理这类“一份数据多目的地”场景的最优解之一。
修改后的路由代码:
from("{{csv.generation}}") .setHeader("dynamicFileName", constant("Main.csv")) // 使用multicast同时分发到两个存储路径 .multicast() .toD("sftp://${properties:ses.sftp.user}@{{ses.sftp.host}}:${properties:${header.country}.sftp.port}${properties:${header.country}.sftp.rdir}?username=${properties:ses.sftp.user}&privateKeyFile={{sftp.prvt.key.path}}&preferredAuthentications=publickey&knownHostsFile={{knownHost.file.path}}&fileName=${header.dynamicFileName}&doneFileName=${header.dynamicFileName}{{cco.files.ready.ext}}") // 给第二个路径指定文件名,避免使用默认的Exchange ID作为文件名 .to("{{save.copy.to.another.path}}?fileName=${header.dynamicFileName}") .end() .log("target csv file has been saved successfully at ${properties:${header.country}.sftp.rdir} SFTP location") .log("Created a copy on Fabric {{save.copy.to.another.path}}${header.dynamicFileName}");
如果需要串行执行(必须等主路径保存成功后再存副本),可以给Multicast加上串行配置:
.multicast().parallelProcessing(false)
方案2:先缓存文件内容再复用
如果不想用Multicast,也可以先把文件内容缓存到Header中,在第一次发送完成后重新设置回消息体,供第二个路径使用:
from("{{csv.generation}}") .setHeader("dynamicFileName", constant("Main.csv")) // 将文件内容缓存到自定义Header中 .setHeader("cachedCsvContent", body()) // 发送到主SFTP路径 .toD("sftp://${properties:ses.sftp.user}@{{ses.sftp.host}}:${properties:${header.country}.sftp.port}${properties:${header.country}.sftp.rdir}?username=${properties:ses.sftp.user}&privateKeyFile={{sftp.prvt.key.path}}&preferredAuthentications=publickey&knownHostsFile={{knownHost.file.path}}&fileName=${header.dynamicFileName}&doneFileName=${header.dynamicFileName}{{cco.files.ready.ext}}") .log("target csv file has been saved successfully at ${properties:${header.country}.sftp.rdir} SFTP location") // 把缓存的内容重新设置回消息体 .setBody(header("cachedCsvContent")) // 发送到第二个路径并指定文件名 .to("{{save.copy.to.another.path}}?fileName=${header.dynamicFileName}") .log("Created a copy on Fabric {{save.copy.to.another.path}}${header.dynamicFileName}");
关键注意点
- 一定要给第二个
to端点指定fileName参数,否则Camel会默认使用Exchange的ID作为文件名,这就是你错误日志中出现/opt/datafiles/5BBCC953F1D3167-0000000000000002这个奇怪文件名的原因。 - 如果你的CSV文件是大文件,缓存到Header可能会占用较多内存,这种情况下优先选择Multicast方案。
内容的提问来源于stack exchange,提问作者Trups
相关产品推荐
相关产品推荐

