Thursday, February 5, 2009

What is wrong with this SOAP message?

We were dealing with an issue with database web services and came across something you don't see very often, an badly formed soap message. Before reading on take a few minutes to look at this message and try to work out what is wrong, there are actually two issues:

<?xml version = '1.0'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <soap:faultcode>
        <soap:Value>soap:Sender</soap:Value>
      </soap:faultcode>
      <soap:faultstring>Error processing input</soap:faultstring>
      <soap:detail>
        ...
      </soap:detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

The most important problem is that the schema for SOAP 1.1 Envelope doesn't define "elementForDefault" so it uses the default "unqualified" form. This requires that non-top level element do not have namespace prefixes. If you examine the schema closely this will mean that Envelope, Body and Fault need an explicit namespace but faultcode et al don't. WS-I basic profile actually has a rule to catch this case. In some cases if in doubt you can run the WS-I testing tools in JDeveloper.

So after fixing the namespace the message looks like:

<?xml version = '1.0'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode>
        <Value>soap:Sender</Value>
      </faultcode>
      <faultstring>Error processing input</faultstring>
      <detail>
        ...
      </detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

This level of confusion is probably why "qualified" is not considered by many to be a better default, for example this is how the SOAP 1.2 specification is defined. We have a audit rule in JDeveloper that makes this suggested fix when it sees it.

There is one final issue in that the faultcode element is wrong. The schema requires a QName, the Value element isn't part of any specification. It it worth noting that schema validation annotation I mentioned previously was a boon for tracking down this error.

The upshot of this is that JAX-WS would be quite happy as a client of this application just as long as it didn't throw a fault. Of course working this out was a team effort with thanks to Alan Davis who did the donkey work and original investigation and Pyounguk for providing the WS-I link.

No comments: