Apache Camel自定义Processor如何保留原始文件名?
如何在Apache Camel自定义处理器中保留原始文件名
我来帮你解决这个问题——在Apache Camel的自定义处理器中保留原始文件名其实很简单,核心是要确保文件名的元数据在Exchange传递过程中不丢失。你当前的代码已经接近正确了,只是在Header传递和路由配置上有一些小问题,下面分两种方案来修复:
方案一:直接复用In消息(最简洁)
如果你只需要修改XML内容,不需要调整其他消息头,直接修改Exchange的In消息体即可,这样原始的文件元数据(包括文件名)会自动保留,不需要手动复制Header:
修改你的处理器代码:
public void process(Exchange exchange) throws Exception { File file = exchange.getIn().getBody(File.class); String fileContents = FileUtils.readFileToString(file); String prettyContents = XMLUtil.formatXml(fileContents); // 直接替换In消息的Body,原始Header(包括文件名)会被保留 exchange.getIn().setBody(prettyContents, String.class); }
路由配置不需要额外修改,保持原样即可:
from("file:{{xslt_out_Event}}?delete=true") .log("Getting file ${file:name}") .process(prettyPrintprocessor) .to("file:{{etl_ready_Event}}");
方案二:使用Out消息并手动传递文件名(适合需自定义Header的场景)
如果你需要完全控制Out消息的内容(比如添加新的Header、修改其他元数据),可以手动将原始文件名传递到Out消息的Header中,同时在路由端点显式指定使用该文件名:
步骤1:修改处理器代码
首先导入Camel的文件常量类(避免硬编码Header键),然后获取并传递原始文件名:
import org.apache.camel.component.file.FileConstants; public void process(Exchange exchange) throws Exception { File file = exchange.getIn().getBody(File.class); String fileContents = FileUtils.readFileToString(file); // 从Camel标准Header获取原始文件名,比file.getName()更可靠 String fileName = exchange.getIn().getHeader(FileConstants.FILE_NAME, String.class); logger.debug("Original file name: {}", fileName); String prettyContents = XMLUtil.formatXml(fileContents); // 设置Out消息的Body exchange.getOut().setBody(prettyContents, String.class); // 将原始文件名设置到Out消息的标准Header中 exchange.getOut().setHeader(FileConstants.FILE_NAME, fileName); // (可选)如果需要保留其他文件相关Header,可复制全部Header // exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders()); }
步骤2:修改路由配置
在to的文件端点中,显式指定使用Header中的文件名,确保Camel不会自动生成新文件名:
from("file:{{xslt_out_Event}}?delete=true") .log("Getting file ${file:name}") .process(prettyPrintprocessor) .to("file:{{etl_ready_Event}}?fileName=${header.CamelFileName}");
为什么之前的代码会丢失文件名?
当你把Exchange的Body从File类型替换为String类型时,Camel的文件组件默认会失去对原始文件元数据的跟踪,此时如果没有手动传递文件名Header,Camel会自动生成一个随机文件名(类似ID-MACHINE-XXX-XXXXXXXXX-0-1)。通过上述两种方法,我们要么复用原始In消息的Header,要么手动传递文件名,就能让输出文件保留原始名称了。
内容的提问来源于stack exchange,提问作者Joshua Glickman
相关产品推荐
相关产品推荐

