5

I have written a web service client (using Java Spring and JAXB Marshaller) that works with the UPS web service. When I send a valid request everything works well. When I send an invalid request (weight > 150 lbs) then the UPS web service responds with a SOAP Fault. The client application just fails with a

org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling 
exception; nested exception is javax.xml.bind.UnmarshalException: 
unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault").

Obviously my program isn't able to decipher the SOAP fault returned by the web service. I wrote a custom FaultMessageResolver, but it doesn't get invoked. Here's the code:

public class UpsRateClient extends WebServiceGatewaySupport {
    public UpsRateClient(WebServiceMessageFactory messageFactory) {
        super(messageFactory);
        getWebServiceTemplate().setFaultMessageResolver(new UpsFaultMessageResolver());
    }

    public RateResponse getRate(RateRequest rateRequest) {
        return (RateResponse) getWebServiceTemplate().marshalSendAndReceive(rateRequest, new UpsRequestWSMC());
    }
    private class UpsFaultMessageResolver implements FaultMessageResolver {
        public void resolveFault(WebServiceMessage message) throws IOException{
            System.out.println("Inside UpsFaultMessageResolver");   
        }
    }
}

Thanks for your time!

user544192
  • 695
  • 2
  • 10
  • 23
  • Take a wireshark trace.My thought is that perhaps the web service sends the SOAP fault using (erroneously) a HTTP 200OK instead of a 500 Internal Server error and your client tries to handle it as a valid response – Cratylus Sep 24 '11 at 22:04
  • You are right! That's what is happening. How do I get around this issue then? Thanks for the reply, user384706! – user544192 Sep 25 '11 at 06:54
  • user544192, can you please point me to some of your code or may be s oem helpful link about how you can calling/consuming the UPS webservice and passing/receiving POJOs? I am having a bit of trouble understanding the way I need to send POJOs to a web service that I need to call. Are you sending any POJO parameters to the web service? If so, then how are you making POJOs in your application that only UPS web service can understand? Appreciate your help. Thanks. – legendofawesomeness Oct 01 '11 at 00:10

2 Answers2

6

I had the same problem (SOAP error with HTTP 200OK) and I solved it setting the CheckConnectionForFault property to false. See.

jddsantaella
  • 3,657
  • 1
  • 23
  • 39
5

Take a wireshark trace.My thought is that perhaps the web service sends the SOAP fault using (erroneously) a HTTP 200OK instead of a 500 Internal Server error and your client tries to handle it as a valid response.
If this is the case this is then the problem lies in the web service which does not addere to SOAP standard(my emphasis):
From SOAP RFC

In case of a SOAP error while processing the request, the SOAP HTTP server MUST issue an HTTP 500 "Internal Server Error" response and include a SOAP message in the response containing a SOAP Fault element (see section 4.4) indicating the SOAP processing error.

If you do not own the web service, they should fix this.
To be honest I am not sure what the work arround would be in Spring-WS.
If I really needed a work arround in Jax-Ws I would replace the stub call with a Dispatcher to handle the raw xml myself and avoid the automatic marshal/demarhal.
Look into Spring-Ws if you can do the same, but this is a bug of the web service, not your client

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • I spoke too soon! I though I saw a 200 OK in wireshark trace. I checked again and now I find that wireshark doesn't tell me the HTTP response code because the web service can be accessed only using https and hence the packets are encrypted. Here's what I found in wireshark Application Data Protocol : http Content Type: Application Data (23) Version: TLS 1.0 Length: 344 Encrypted Application Data: ecb93a7325f8442b032513d7... Sorry for wasting your time, user384706! Is there an easy way to capture the status code from the response? – user544192 Sep 25 '11 at 16:52
  • Here's what I found in the log file: Sent request [SaajSoapMessage {http://www.ups.com/XMLSchema/XOLTWS/Rate/v1.1}RateRequest] Received response [SaajSoapMessage {http://schemas.xmlsoap.org/soap/envelope/}Fault] for request [SaajSoapMessage {http://www.ups.com/XMLSchema/XOLTWS/Rate/v1.1}RateRequest] – user544192 Sep 25 '11 at 16:53
  • Thanks for the valuable advice, user384706! I used soapUI to verify the http response code and the response soap envelope. I found that the SOAP Fault has been returned with a HTTP 200 rather than a HTTP 500, like you've suspected. You are genius for having guessed that! Thanks again! – user544192 Sep 26 '11 at 18:50
  • 1
    In fact I took advantage of his answer. Because I had exactly that problem: a Fault and and a 200OK answer. And in the future, in case you want to check header and body inmeadiatle.. you can use Wireshark but I would rather use soapUI. ;) –  Nov 14 '11 at 15:58
  • 1
    OP- I appreciate your enthusiasm, but what is the solution here for Spring-WS? – IcedDante May 14 '14 at 05:00