You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Apache Camel的RouteBuilder中获取Out Message?

问题分析与解决方案

你遇到的核心问题是:文件组件(File Component)的Producer行为是单向写入文件,不会等待路由后续的Webhook调用结果,所以producerTemplate.requestBody返回的只是你写入文件的原始JSON,而非Webhook的响应。

要解决这个问题,需要调整路由结构,使用支持请求-响应模式的端点作为主动调用的入口,同时保留文件读取的功能。

具体修改方案

1. 重构RouteBuilder,拆分路由逻辑

将主动调用和文件读取的逻辑分离,用direct端点作为同步调用的入口,文件路由复用该逻辑:

public class WebhookRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        // 同步调用入口:direct端点,支持请求-响应模式
        from("direct:invoke-webhook")
            .log("Received message: ${body}")
            .process(new WebhookProcessor())
            .log("Invoking webhook with headers: ${headers}")
            .log("Invoking webhook with body: ${body}")
            .toD("${header." + HTTP_URI + "}")
            .end();

        // 文件读取路由:读取文件后转发到direct端点处理
        final String messageSource = "/tmp/messages/webhook";
        from(messageSource)
            .to("direct:invoke-webhook")
            .log("Webhook response for file ${header.CamelFileName}: ${body}")
            .end();
    }

    // WebhookProcessor保持不变
    protected class WebhookProcessor implements Processor {
        public void process(Exchange exchange) throws Exception {
            try {
                Message message = exchange.getIn();
                JsonNode json = JacksonUtils.getObjectMapper().readTree(message.getBody(String.class));

                message.setHeader(HTTP_URI, json.get("targetUrl").asText());
                message.setHeader(HTTP_METHOD, "POST");
                message.setHeader(HttpHeaders.CONTENT_TYPE, json.get("contentType").asText());
                final String username = json.get("username").asText();
                final String password = json.get("password").asText();
                if (username != null && password != null) {
                    String encodedAuth = Base64.getEncoder().encodeToString(String.format("%s:%s", username, password).getBytes(StandardCharsets.UTF_8));
                    message.setHeader(HttpHeaders.AUTHORIZATION, String.format("Basic %s", encodedAuth));
                }
                message.setBody(json.get("body").asText());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2. 修改ProducerTemplate调用逻辑

将消息发送到direct:invoke-webhook端点,而非文件路径,这样就能同步获取Webhook的响应:

private static CamelContext camel;
private static ProducerTemplate producerTemplate;

...

if (camel == null) {
    camel = new DefaultCamelContext();
    camel.addRoutes(new WebhookRouteBuilder());
    producerTemplate = camel.createProducerTemplate();
    camel.start();
}

final String webhookJson = JacksonUtils.getObjectMapper()
    .writerWithDefaultPrettyPrinter()
    .writeValueAsString(webhook);

// 发送到direct端点,获取Webhook响应
Object result = producerTemplate.requestBody("direct:invoke-webhook", webhookJson);

3. 获取完整Exchange(若需要)

如果要获取响应头、状态码等完整Exchange信息,可使用request方法:

Exchange exchange = producerTemplate.request("direct:invoke-webhook", ex -> ex.getIn().setBody(webhookJson));
Message responseMessage = exchange.getOut();

// 获取响应体
String responseBody = responseMessage.getBody(String.class);
// 获取响应头(如状态码)
Integer statusCode = responseMessage.getHeader(HTTP_RESPONSE_CODE, Integer.class);
String contentType = responseMessage.getHeader(HttpHeaders.CONTENT_TYPE, String.class);

关键原理说明

  • 文件组件的Producer仅负责将内容写入文件,写入完成后立即返回原始内容,路由中from(messageSource)的后续处理是异步执行的,因此无法通过producerTemplate获取Webhook响应。
  • direct端点是同步的请求-响应模式,消息会在同一个线程中走完整个路由流程,处理完成后才返回结果,完美匹配你主动调用并获取响应的需求。

内容的提问来源于stack exchange,提问作者Martin Smithson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:27:40