Apache Camel中使用CXF组件为何无法读取HTTP响应码?
问题原因分析
CamelHttpResponseCode头的适用范围:这个头是Camel HTTP组件(如Jetty、Undertow)的专属头,你的路由使用的是CXF WebService端点,CXF不会自动填充这个头字段。onCompletion()的执行时机:默认情况下onCompletion()会在交换完成前触发,此时响应头还未被写入交换;另外,即便存在响应码头,也会存储在out.header而非in.header中(响应属于输出侧数据)。
解决方案
方案1:针对CXF服务端(你的当前场景)
要捕获CXF服务端返回的HTTP响应码,需要通过CXF拦截器提取状态码并写入Camel交换属性,再在日志中读取:
1. 自定义CXF输出拦截器
public class HttpStatusCodeInterceptor extends AbstractOutInterceptor { public HttpStatusCodeInterceptor() { super(Phase.PRE_STREAM); } @Override public void handleMessage(Message message) throws Fault { // 从CXF Message中获取HTTP响应码 Integer statusCode = (Integer) message.get(Message.RESPONSE_CODE); // 将状态码存入Camel交换属性 Exchange camelExchange = message.getExchange().get(Exchange.class); if (camelExchange != null) { camelExchange.setProperty("HttpResponseCode", statusCode); } } }
2. 配置CXF端点添加拦截器
from( cxf("/test") .wsdlURL("wsdl/wsdl.wsdl") .serviceClass("org.tempuri.Class") .dataFormat(DataFormat.POJO) .advanced() .schemaValidationEnabled(true) // 注册自定义拦截器 .outInterceptors(Collections.singletonList(new HttpStatusCodeInterceptor())) ) .to(direct("route"));
3. 修改onCompletion()日志逻辑
调整执行时机为交换完成后,读取自定义交换属性:
onCompletion() .afterConsumer() // 确保在响应生成后执行 .log("${in.header.operationName} - ${exchangeProperty.HttpResponseCode}");
方案2:如果是CXF客户端场景(调用外部WebService)
若你的路由是作为客户端调用外部CXF服务,CXF客户端组件会自动将HTTP响应码写入out.header.CamelHttpResponseCode,直接读取即可:
from("direct:invokeWs") .to("cxf:http://external-service.com/test?serviceClass=org.tempuri.Class&dataFormat=POJO") .log("${in.header.operationName} - ${out.header.CamelHttpResponseCode}");
内容的提问来源于stack exchange,提问作者Michał
相关产品推荐
相关产品推荐

