6

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

Carlos
  • 1,340
  • 1
  • 10
  • 26
  • See if this helps http://cxf.547215.n5.nabble.com/CXF-Fault-Response-Code-td566788.html – Tarun Lalwani Apr 11 '18 at 08:05
  • hi @TarunLalwani , the problem I have is on the client side (I am invoking services). – Carlos Apr 11 '18 at 12:56
  • did you get any solutions ? – Ganesh Gudghe May 31 '19 at 08:35
  • @ganeshGudghe unfortunately not with the apache cxf client. I hoped some developer of the library could help but no luck. My suggestion is to try another library or go lower level and invoke directly (look class HttpURLConnection). With this class and consuming the stream in the response you will succeed. Forget of the convenience of using objects, you will have to build a string with all the soap request. – Carlos May 31 '19 at 16:22

1 Answers1

-2

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>
Hans Schreuder
  • 745
  • 5
  • 10
  • The wsdl is a contract specified by the server (which is a 3rd party). I do not modify wsdls, not a good practice IMO. The reason why I made an interceptor was trying to obtain the fault code and fault string sent in the response of the server. – Carlos Apr 17 '18 at 11:45
  • Making WSDL's is not that hard, you have editors for it. And why not, I expect you know the interface. But will look if I can find a solution for what you want. – Hans Schreuder Apr 17 '18 at 13:52