Carlos
Carlos

Reputation: 1450

Apache CXF client soap fault handling

I am using apache cxf client 3.2.2 in a standalone java application to make invocations to some soap webservices.

Trying to get the soap fault code and fault string in a one way operation but without success.

I have defined a custom interceptor but it never reaches the handleMessage

 IncomingFaultInterceptor faultInterceptor = new IncomingFaultInterceptor();
    cxfEndpoint.getInFaultInterceptors().add(faultInterceptor);

The code from the custom interceptor

public class IncomingFaultInterceptor extends AbstractSoapInterceptor {

public IncomingFaultInterceptor(){
    super(Phase.RECEIVE);
}


@Override
public void handleMessage(SoapMessage message) throws Fault {
    if(message != null){
        /* log fault string , fault code*/ 
    }


}

}

The exception I am getting is in MessageSenderEndingInterceptor (which is in the PREPARE_SEND phase).

It is throwing a new Fault, with the text "Could not send message". What is strange is that the exception catched is "HTTP response '500: Internal Server Error' when communicating with ..."

If I send the same request with soapui I see the fault code and fault string

HTTP/1.1 500 Internal Server Error
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml;charset=utf-8
Content-Length: 396
Date: Thu, 05 Apr 2018 15:32:27 GMT
Connection: close
Server: Test

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode xmlns:ns0="http://company.com/services/fault">THE_FAULT_CODE</faultcode>
      <faultstring xml:lang="en">THE_FAULT_STRING</faultstring>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Any ideas, or what can I do to get the fault code and fault string? Any good documentation of client interceptors in cxf?

Update:

Seems it is not possible to get the fault code and fault string in a one way operation with cxf client as the server does not meet SOAP and WSI standards.

Anyway I was not able to bypass the exception and log the fault string and fault code. Tried commenting the one way annotation in the generated code but still the interceptor never gets executed. I could not find good examples on how to implement an interceptor on the client side to handle faults.

More info:

The specification of WS-I for one way operations. From the definition "..For example, a "500 Internal Server Error" HTTP response that contains a fault can not be returned in this situation."

Apart from this, the error "Could not send message" is quite confusing as the request was sent but it is already reported here

Upvotes: 6

Views: 7863

Answers (1)

Hans Schreuder
Hans Schreuder

Reputation: 753

Do not understand why you make your own interceptor.

look here: http://cxf.apache.org/docs/developing-a-consumer.html

If you explicit describe the fault in your WSDL, the fault class is generated and you can just catch it.

You can specify the fault message there.

<wsdl:operation name="pingMe">
    <wsdl:input name="pingMeRequest" message="tns:pingMeRequest"/>
    <wsdl:output name="pingMeResponse" message="tns:pingMeResponse"/>
    <wsdl:fault name="pingMeFault" message="tns:pingMeFault"/>
</wsdl:operation> 

<wsdl:message name="pingMeFault">
    <wsdl:part name="faultDetail" element="x1:faultDetail"/>
</wsdl:message>

Upvotes: -2

Related Questions