Apache Camel DSL基于内容路由CSV文件,处理器未触发问题排查
Apache Camel CSV路由未触发处理器问题排查
我来帮你分析下问题所在,主要有两个核心问题导致你的处理器没被触发,而且Camel启动后立刻就关闭了:
1. Camel上下文过早关闭
从日志能看到,Camel刚启动完成就开始shutdown了,这是因为你的主线程在启动Camel上下文后没有保持活跃,JVM直接退出了。Camel的路由是在后台线程运行的,如果主线程结束,整个程序就终止了,路由自然没法处理文件。
解决办法很简单,在启动Camel上下文后,让主线程保持运行状态:
public static void main(String[] args) throws Exception { CamelContext context = new DefaultCamelContext(); // 这里添加你的路由配置代码 context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { // 把你的三个路由逻辑写在这里 } }); context.start(); // 让主线程一直阻塞,避免JVM退出 Thread.sleep(Long.MAX_VALUE); // 如果用Camel的Main类,更推荐用下面的方式: // Main main = new Main(); // main.addRouteBuilder(new YourRouteBuilder()); // main.run(); }
2. CSV头过滤逻辑错误
你当前用body().contains("partyName")来判断文件头,但File组件默认把文件内容作为InputStream传递,直接对InputStream调用contains方法根本不会生效(这不是字符串的contains逻辑)。另外,你的CSV文件头是带双引号的(比如"partyName"),你的判断条件也没匹配引号,即使转成字符串也会判断失败。
修正后的路由1应该先把InputStream转换成字符串,再匹配带引号的头:
CsvDataFormat csv = new CsvDataFormat(); from("file:/home/r2/Desktop/csvFile?noop=true") // 先把文件流转换成字符串,才能进行内容匹配 .convertBodyTo(String.class) .choice() // 匹配带双引号的头,和你的CSV文件格式一致 .when(body().contains("\"partyName\"")) .to("direct:partyNameCSV") .when(body().contains("\"stuffName\"")) .to("direct:stuffNameCSV") .otherwise() .log("Skipping file with unrecognized header: ${file:name}") .endChoice();
如果你想更高效,只读取文件第一行(表头)来判断,而不是加载整个文件内容,可以用这种方式:
from("file:/home/r2/Desktop/csvFile?noop=true") .process(exchange -> { InputStream is = exchange.getIn().getBody(InputStream.class); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String headerLine = reader.readLine(); // 把读取后的流重新放回exchange,避免后续unmarshal时流已被读取 exchange.getIn().setBody(new SequenceInputStream(new ByteArrayInputStream((headerLine + "\n").getBytes()), is)); exchange.setProperty("CSV_HEADER", headerLine); }) .choice() .when(exchangeProperty("CSV_HEADER").contains("\"partyName\"")) .to("direct:partyNameCSV") .when(exchangeProperty("CSV_HEADER").contains("\"stuffName\"")) .to("direct:stuffNameCSV") .endChoice();
把这两个问题修复后,你的路由应该就能正常触发处理器了。
内容的提问来源于stack exchange,提问作者Rajat.r2
相关产品推荐
相关产品推荐

