在ApacheCamel的CXF组件POJO模式下,HTTP响应码CamelHttpResponseCode不在消息头,而在消息体Map中,需通过${in.body[CamelHttpResponseCode]}获取。onCompletion()是获取响应码的稳妥方式,且需注意声明位置。
在使用 Apache Camel 的 CXF 组件调用 WebService 时,您是否遇到过想要获取 HTTP 响应码却总是无法获取的情况?一个常见的误区是:许多开发者习惯性地去 in.headers 中查找 CamelHttpResponseCode,结果发现它始终为空。实际上,该值并不存在于那里。
首先需要明确一个核心问题:在 Apache Camel 中使用 CXF 组件(默认 POJO 模式)时,CamelHttpResponseCode 并不位于 in.headers 中,而是作为消息体(Message Body)的属性存在。正确的访问方式应为 ${in.body[CamelHttpResponseCode]},而非 ${in.header.CamelHttpResponseCode}。
长期稳定更新的攒劲资源: >>>点此立即查看<<<

为何会出现这种情况?这源于 CXF 组件的处理机制。默认情况下,它采用 POJO 模式(DataFormat.POJO)处理 SOAP 请求与响应,底层通过 CXF 的本地 JVM 调用进行,而非直接连接 HTTP 传输层。因此,HTTP 状态码(如 200、500)并非标准 HTTP 响应头的一部分。Camel 在封装响应时,由 CXF Transport 或 Camel 的 CxfEndpoint 自动将其注入到 Exchange 的 in.body 属性映射中,键名即为 CamelHttpResponseCode。
这意味着:
正确访问方式为 ${in.body[CamelHttpResponseCode]}(即从 Message.getBody(Map.class) 中取值);
${in.header.CamelHttpResponseCode} 始终为空,因为该值从未写入 headers。
onCompletion() 会在路由完成(包括所有后续 .to() 处理)之后触发,此时 Exchange 已完整承载响应数据,是获取响应码的最稳妥方式:
from(cxf("/test") .wsdlURL("wsdl/wsdl.wsdl") .serviceClass("org.tempuri.Class") .dataFormat(DataFormat.POJO) .advanced().schemaValidationEnabled(true)) .to("direct:route") .onCompletion() .log("${in.header.operationName} - ${in.body[CamelHttpResponseCode]}");
注意:
onCompletion()必须置于.to(...)之后。若放在from(...)后立即声明,它会在请求发出后、响应尚未返回前就执行,导致CamelHttpResponseCode尚未注入,日志输出为 null 或空字符串。
如果不确定响应结构,可在路由中插入一个临时处理器,直接查看实际内容:
.process(exchange -> { Object body = exchange.getIn().getBody(); Map, ?> bodyMap = body instanceof Map (Map, ?>) body : Collections.emptyMap(); log.info("Response body keys: {}", bodyMap.keySet()); log.info("CamelHttpResponseCode = {}", bodyMap.get("CamelHttpResponseCode"));})
常见键还包括 CamelHttpResponseText(如 "OK")、CamelHttpUri、operationName(来自 WSDL 操作名)等,这些均可作为调试线索。
DataFormat.PAYLOAD 或 DataFormat.RAW,且底层启用了 HTTP Transport(例如 cxf:http://...),则可通过 Exchange.HTTP_RESPONSE_CODE header 获取真实状态码。但前提是必须配置 httpClientConfigurer 启用 HTTP 协议栈。local:// transport),此时 CamelHttpResponseCode 仅为 Camel 模拟的“逻辑状态码”,通常为 200(成功)或 500(CXF 抛出 Fault)。它并非原始 HTTP 连接的真实状态码,这一点需格外留意。| 场景 | 获取方式 | 说明 |
|---|---|---|
| POJO 模式(默认) | ${in.body[CamelHttpResponseCode]} | 值由 Camel/CXF 注入到 body map,最可靠 |
| Payload 模式 + HTTP Transport | ${in.header.Exchange.HTTP_RESPONSE_CODE} | 需显式配置 HTTP client,依赖网络层 |
| 日志中动态拼接 | ${in.header.operationName} - ${in.body[CamelHttpResponseCode]:200} | 支持默认值 fallback(:200)避免 null |
按照上述方式操作,即可稳定输出形如 sayHello - 200 的日志,精准反映服务调用结果的状态。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述