Monday, January 26, 2009

Schema Validation for JAX-WS

We had a very simple test case that confused myself and Alan, the replacement Alan not the old one, for a few minutes today. Our web service looked like this:

@WebService
public class Echo {
    public int echoInt (int i) {
        return i;
    }

}

But when we passed in invalid data to the web service the value of i was 0. So here is example message that JAX-WS will consume properly; but is obviously invalid:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://project1/">
   <env:Header/>
   <env:Body>
      <ns1:echoInt>
         <arg0>xxxx</arg0>
      </ns1:echoInt>
   </env:Body>
</env:Envelope>

It took us a while to remember that schema validation is optional, (See section 1.1 of the JAX-WS specification), and that there is no standard way to turn it on. The RI on the other hand does provide a way and it is as simple as sticking in a annotation. It also has some cool stuff for handling and ignoring specific errors which I find interesting; but I don't have a use case for yet.

import com.sun.xml.ws.developer.SchemaValidation;

@WebService
@SchemaValidation()
public class Echo {
    public int echo (int i) {
        return i;
    }
}

With our previous test data you now get a fault back:

<?xml version = '1.0' encoding = 'UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>com.sun.istack.XMLStreamException2: org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'xxxx' is not a valid value for 'integer'.</faultstring>
         <detail>
            ...
         </detail>
      </S:Fault>
   </S:Body>
</S:Envelope>

Of course there are performance reasons why you might not want to validate the incoming message but it could make your service code much easier if you know it doesn't have to deal with invalid data. Also this is part of the RI so subject to change more than the -WS straight.

5 comments:

Bing Luo said...

have you find the way to display error location using e.getLineNumber() and e.getColumnNumber()? I always get -1. do not know why.

Gerard Davison said...

No idea about the -1 issue I am affraid

nick said...

http://one-size-doesnt-fit-all.blogspot.com/2009/04/jax-ws-schemavalidation-custom-handler.html

Andrew said...

if I use the annotation @SchemaValidation() it only displays without detail.

S:Server
com.sun.istack.XMLStreamException2

I would be interested what configuration and version of JAXWS do you use?

Gerard Davison said...

I am pretty sure it was JAX-WS 2.1.4 when I wrote this blog.

Gerard