在ApacheCamel的CXF组件POJO模式下,HTTP响应码CamelHttpResponseCode不在消息头,而在消息体Map中,需通过${in.body[CamelHttpResponseCode]}获取。onCompletion()是获取响应码的稳妥方式,且需注意声明位置。
Apache Camel中从CXF组件获取HTTP响应码的正确方式
时间:2026-07-12
浏览:460
文章目录
在使用 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() 获取响应码
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 操作名)等,这些均可作为调试线索。
补充说明:何时能获取真实的 HTTP 状态码?
- 如果使用
DataFormat.PAYLOAD或DataFormat.RAW,且底层启用了 HTTP Transport(例如cxf:http://...),则可通过Exchange.HTTP_RESPONSE_CODEheader 获取真实状态码。但前提是必须配置httpClientConfigurer启用 HTTP 协议栈。 - 但在 POJO 模式下,默认走的是 JVM 内部调用(
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 的日志,精准反映服务调用结果的状态。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。