骆驼和CXF:如何获取出站消息?

Camel and CXF: How to get the outbound message?

我有这条骆驼路线:

    from("cxf:bean:endpointDocs01?loggingFeatureEnabled=true")
    .to("direct:CBR") 
    .transform().method(WebServiceUtils.class,"response()")
    .log("Outbound message: ${body}");

endpointDocs01 在蓝图中定义如下:

<cxf:cxfEndpoint address="/documentos/" id="endpointDocs01"
    serviceClass="com.adelco.webservice.ServiceDocs" wsdlURL="wsdl/wsdl03.wsdl">
    <cxf:properties>
        <entry key="schema-validation-enabled" value="true"/>
    </cxf:properties>
</cxf:cxfEndpoint>

这条路线没有任何问题,包括模式验证。

当我发送正确的请求时,我可以使用交换的最后一行“.log("Outbound message: ${body}"。在这个案例,日志显示:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <outputDocumento xmlns="http://webservice.adelco.com">
         <respuesta>0</respuesta>
         <mensaje>El mensaje [113282] fue recibido. Fecha recepción Wed Apr 12 17:01:11 CLT 2017</mensaje>
       </outputDocumento>
    </soap:Body>
</soap:Envelope>

但是,当我发送不正确的请求时,“.log("Log outbound message: ${body}" 行什么都不做。但是我在客户端得到了响应(Soap:Fault 响应)

 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
          <faultcode>soap:Client</faultcode>
          <faultstring>Unmarshalling Error: cvc-complex-type.2.4.a: Invalid content was found starting with element 'Sociedad'. One of '{"http://webservice.adelco.com":TipoMovimiento}' is expected.</faultstring>
       </soap:Fault>
    </soap:Body>
 </soap:Envelope>

为什么这个 soap:Fault 响应没有记录?

您的路由在 解组后被调用。因此,如果由于无效输入导致解组失败,路由不会触发,也不会记录。

阅读这篇关于 CXF architecture 的文章。

Phase Interceptors
CXF provides an InterceptorChain implementation called the PhaseInterceptorChain. [...]
Let us take a hypothetical simplified example (NOTE: these phases and interceptors don't necessarily exist in CXF). Let us say we are parsing a SOAP message. We may want to have two phases. First, a dispatch phase which parses the soap headers and determines which service to route the Message to. Second, an unmarshal phase which binds the SOAP body to JAXB objects.
Fault Handling
At any point during processing, an interceptor may throw a Fault, or a derivative of a Fault like the SoapFault. This will cause the chain to stop invoking and unwind it. Unwinding consists of calling handleFault on each interceptor that was invoked in reverse order.

当发生故障时,处理停止,拦截器链展开。 CXF 对消息(输入和输出)和故障(输入和输出)使用不同的链。

使用自定义 bean(必须实现 PhaseInterceptor 接口)作为拦截器:

<cxf:cxfEndpoint address="/documentos/" id="endpointDocs01"
    serviceClass="com.adelco.webservice.ServiceDocs" wsdlURL="wsdl/wsdl03.wsdl">
    <cxf:properties>
        <entry key="schema-validation-enabled" value="true"/>
    </cxf:properties>
    <cxf:inInterceptors>
        <ref component-id="inInterceptorBean" />
    </cxf:inInterceptors>
    <cxf:outInterceptors>
        <ref component-id="outInterceptorBean" />
    </cxf:outInterceptors>
    <cxf:outFaultInterceptors>
        <ref component-id="outFaultInterceptorBean" />
    </cxf:outFaultInterceptors>
</cxf:cxfEndpoint>

正如@Allesandro 所说,链条会在失败时松开。

您可以添加一个 onException 子句:

onException(ValidationException.class)
  .log("Outbound message: ${body}");

from("cxf:bean:endpointDocs01?loggingFeatureEnabled=true")
.to("direct:CBR") 
.transform().method(WebServiceUtils.class,"response()")
.log("Outbound message: ${body}");