This week's giveaway is in the Threads forum.
We're giving away four copies of Java Concurrency Live Lessons and have Doug Schmidt on-line!
See this thread for details.
Win a copy of Java Concurrency Live Lessons this week in the Threads forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Can the cause of exception be identified at client in case of improper SOAP fault as response?  RSS feed

 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Everyone,
Details:
This is a SOAP service invoked from Java.
Currently client is not getting a proper SOAP fault, but getting a HTTP 401 error wrapped in com.sun.xml.internal.ws.client.ClientTransportException.
This is the response in SoapUI in case of SOAP fault.

It is clear from the response that <detail> node is not compliant with the XSD (http://schemas.xmlsoap.org/soap/envelope/).
So my question is, can actual fault cause be identified at client somehow or modifying the service to repair the <detail> node is the only option?
 
g tsuji
Ranch Hand
Posts: 697
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is clear from the response that <detail> node is not compliant with the XSD (http://schemas.xmlsoap.org/soap/envelope/).

This is quite true and it is indeed something concrete implementations might elect to preferring tacitly a mixed="true" at the detail element's construction for perhaps legacy or backward compatibility consideration... This is a dark corner. It is of course better not to emit a simple content detail element in a soap response fault code. For instance, WebLogic does allow a detail element construction likewise. But, it is better to avoid it in the normal course of business?! That's common sense.

So my question is, can actual fault cause be identified at client somehow or modifying the service to repair the <detail> node is the only option?

If by"fault cause" you actually mean to looking into the <detail> content, you sure can. If the client is coded in JAX-WS approach, it often happens to capture the lower level SOAPMessageContext via a handler within the handler chain. In any case, once you get a handler of SOAPMessage, you can obtain in consequence easily SOAPBody, and hence SOAPFault by .getFault() method.

Once you have the instance of SOAPFault (say, sFault), the instance of detail element (say, detail) is only one step away by sFault.getDetail() which is a subclass of SOAPElement which in turn is a subclass of w3c.xml.dom.Node. Rather than using getDetailEntries() to set up the iterator to iterate through the entries, you can determine that this time there is no entries at all and you "judiciously" do one more thing, that is to run the detail.getTextContent() to get the text node of the detail element. And that would give you "Access failure for API: /soap/pim/Product, version: 1.0 with key: 6cff3a7ef6469ca657adf8eb5ee65a54", the data you want to extract to determine what action to take accordingly.

You can also take a more elaborated approach where you wrap the simple text content by an element of local-name and namespace your application recognizes and anticipates. This is to happen again in a handler intercepting the SOAPMessage (in particular within the handleFault(...) method of the handler you've to implement. That particular implementation for that to happen is not too difficult, but you still have to write it and that may irritates some people!

That's about all I can set out for you to consider doing.
 
Tapas Chand
Ranch Hand
Posts: 614
9
BSD Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry for coming late.
g tsuji wrote:...If the client is coded in JAX-WS approach, it often happens to capture the lower level SOAPMessageContext via a handler within the handler chain. In any case, once you get a handler of SOAPMessage, you can obtain in consequence easily SOAPBody, and hence SOAPFault by .getFault() method.

Once you have the instance of SOAPFault (say, sFault), the instance of detail element (say, detail) is only one step away by sFault.getDetail()...

Thank you g tsuji for your inputs. :)
The client is indeed built using JAX-WS.
I have tried putting a handler, but in my case flow is not coming at all inside "handleMessage(SOAPMessageContext context) method" in case of inbound, nor flow is coming inside "handleFault(SOAPMessageContext context) method".
NOTE: Handler is working fine as outbound flow is logged properly.

Further updates:
At server side they have repaired the SOAP fault response, now it is looking something like this, which conforms the XSD, so valid.

Still I am not getting a SOAP fault in my JAX-WS client, but getting HTTP 401.
After few hours of search, we came across following.
JAX-WS conforms to “WS-I Basic Profile 1.1”, which says HTTP status code must be 500 in case of any SOAP fault. Then only client will get a SOAP fault.

In our case though server is sending correct format of SOAP fault, yet it is sending HTTP status code 401 for expired token.
Because of this, the client is unable to get SOAP fault sent by server.

So now I think, if I want to keep web service client unchanged, server has to send HTTP 500 instead of HTTP 401 in my case.
If not possible, next option may be server sends the fault "detail" in HTTP header so that I get the information using "javax.xml.ws.handler.MessageContext.HTTP_RESPONSE_HEADERS".

Kindly share if anyone has anything more to add.

Reference links for the above findings.
  • https://mxforum.mendix.com/questions/5740/Your-opinion-on-HTTP-status-codes-for-webservice-faults
  • http://www.ws-i.org/profiles/basicprofile-1.1-2004-08-24.html
  • https://docs.oracle.com/javaee/6/tutorial/doc/bnazd.html



  •  
    g tsuji
    Ranch Hand
    Posts: 697
    3
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You seem to have some definite opinion, so I will leave you do you own research and take on an approach to your liking. Whereas I don't necessarily agree with your statement:
    NOTE: Handler is working fine as outbound flow is logged properly

    I don't think handlers have an inherent asymmetric functionality detrimental to inbound message. On can simply check out the context's property of MessageContext.MESSAGE_OUTBOUND_PROPERTY via the get() method to determine if it is inbound or outbound and do thing accordingly.

    I have tried putting a handler, but in my case flow is not coming at all inside "handleMessage(SOAPMessageContext context) method" in case of inbound, nor flow is coming inside "handleFault(SOAPMessageContext context) method".

    If the response is a SoapFault, it would surely not be captured by the handleMessage, it is the handleFault method which would process it before passing to the calling client application or the next handler in the handler chain (and I think HTTP status, rightly or wrongly sent, is not the prime reason that the SOAPMessage be diverted to I don't know where! ...) But you say it is so happened in your case, I wouldn't challenge that, only that it is not my understanding and I have some reserve on that statement. At the end, my opinion does not matter. Good luck.
     
    Tapas Chand
    Ranch Hand
    Posts: 614
    9
    BSD Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thank you for your inputs.
    g tsuji wrote:...it would surely not be captured by the handleMessage, it is the handleFault method which would process it before passing to the calling client application...

    That is exactly what is happening in case server is returning SOAP fault with HTTP status code 500.
    When server is returning SOAP fault with HTTP status code 401, Exception is occurring somewhere before SOAPHandler coming into picture and application is not getting a "javax.xml.ws.soap.SOAPFaultException", but getting a "com.sun.xml.ws.client.ClientTransportException".

    Anyways they have modified their code at server and returning HTTP 500 now for SOAP faults.
    And my client is getting a SOAPFaultException now and able to get all the details sent by server as SOAP fault and seems very happy now.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!