Sometimes you just wish software architects weren't so creative or,
at least, were more coordinated. It seems that's what happened with
SOAP, the standard format for web services messages. The SOAP
specification started out defining a lot of protocol-specific XML
structures that now, in hindsight, could obviously better be delegated
to the W3C XML Schema language, the whole purpose of which is to
define the structure of XML documents. It's a disconnect that the Java
community is still working out.

In this article we'll explore the oft-misunderstood relationship
between Java web services platforms and the W3C XML Schema (WXS)
binding frameworks that convert between XML and XML-agnostic
objects. And we'll look at how to leverage schema binding using
various Java Web services toolkits and runtimes.

Reconciling Web services with XML Schema

In May 2000, when the World Wide Web Consortium published SOAP
1.1, the W3C XML Schema specification was still only in draft
stages.

SOAP 1.1 encourages a way of encoding XML that relies on placing
simple type values in element bodies. But where SOAP
encoding, as it is called, really digresses from WXS is in its
use of in-document references and a SOAP-specific
Array type.

SOAP 1.1 also suggests a way of associating SOAP messages with
remote procedure calls. RPC imposes certain conventions and
restrictions on the XML elements that correspond to parameters or
return values and the method-matching XML elements that
automatically wrap them.

By the time in May 2001 the W3C finalized its XML
Schema specification, more WXS-reliant alternatives to SOAP
encoding and RPC style had arisen.

As opposed to SOAP encoding, literal XML usage says XML
should be written precisely the way it's defined in a schema. No
more complicated references or SOAP-encoded arrays. In a Web Services
Description Language (WSDL) 1.1 document, a use
attribute in certain SOAP-specific elements can be set
to encoded or literal.

As opposed to RPC style, document style tells a runtime to write the
XML exactly as it's defined in the WSDL. In the WSDL, each message
element should contain a single part element, which in turn refers
to an element defined in a schema. Conveniently, the XML schemata appear directly
-- or indirectly via imports -- under the types element of a WSDL,
using a path like so:

/wsdl:definitions/wsdl:types/xsd:schema

In WSDL, a style attribute in certain SOAP-binding elements can
be set to "rpc" or "document".

Document/literal Web services are well on their way to replacing
RPC/encoded as an industry standard. The Web Services
Interoperability Organization (WS-I), a consortium whose goal is
make sure Web services and clients play nice together, published in
August 2003 a set of guidelines called the Basic
Profile Version 1.0a. The Basic Profile prohibits the use of
SOAP encoding; it does allow RPC style, although the RPC/literal
combination has never caught on.

The nice thing about document/literal is that it forces the actual payload
of a SOAP message to be defined entirely using W3C XML Schema, independent of
SOAP and WSDL. The child of the soap:Body element, as shown in
the SOAP message structure below, can stand alone as its own XML document:

This is the kind of encapsulation that should make a design patterns aficionado
go weak at the knees. Not only could the SOAP body's contents readily be validated
against a schema, but if the web services platform leverages a schema binding
framework with a public API, the same schema can be used to serialize XML not
just to a SOAP message but to any destination: a file, as a node within a larger
document, whatever.

Here's another nice thing, if you consider a whole can of worms a
nice thing. Once you're using a full-fledged schema binding
framework, you can customize how you bind between Java classes and
WXS data types. Consider the beginning of a JavaBean-style class
definition below:

Simple question: do you define the key property as an
XML element or attribute? With SOAP encoding, you have no choice but
to make it an element. With literal use, there are two ways to
go:

Just as with SOAP encoding, the binding toolkit makes the choice
for you. This is what the open-source Web services platform Apache Axis 1.2 does.

The toolkit gives you a choice.

If you don't want to control the XML in your web service, the
former, default-only approach is an acceptable option. But if you do
want to exploit the schema's constructs or you're generating a
client for a service that does, then the latter approach, involving
a real schema binding framework, is required.

A Java binding framework provides a schema-to-Java tool, possibly also a Java-to-schema
tool. If a web services provider incorporates the schema binding provider, then
WSDL-to-Java and Java-to-WSDL tools should perform a superset of the schema-only
tools' functionality.

So where do the binding/mapping customizations go? Some "to-Java" tools place
them in the plumbing of the generated implementation classes themselves, although
that tends to rule out a "Java-to" reverse conversion. Other to-Java tools produce
an extra output besides source code, namely a proprietary XML mappings file,
which in turn becomes an extra input to the corresponding Java-to tool (if present).
Accordingly, the runtime checks the customizations as it translates between
XML instance documents and objects.

Employing the same XML serializer on both ends

We're ready to try to exploit the synergy between schema binding and web services.
We'll use what we might call a naïve implementation, where we define the
same XML document for publishing over the Web service and for serializing to
disk. Suppose the service endpoint interface defines these methods:

The FooDocument class corresponds to
a foo.xsd schema definition that gets imported into the
web service's generated WSDL. The web service runtime receives
an update SOAP message and automatically deserializes
the XML into a FooDocument instance. (Normally, you'll
use a "wrapped" interpretation of a document-style web service where
the request
soap:Body element's child is not the foo element but
rather an extra wrapper element that the Web service platform has automatically
defined in the WSDL.)

You can then implement the Persistence interface using
the same binding framework the Web services platform
uses. The writeObject2Document implementation obtains a
writer or output stream and calls an appropriate object
serialization method in the binding framework
API. Likewise, readDocument2Object, which is called
by getFoo, calls the appropriate deserialization
method. The translation between an entire XML document and an entire
object graph should be accomplished in a few method calls; no need
to write DOM or SAX code or otherwise get your hands dirty with the
XML.

There are a few reasons this example might be considered a naïve implementation:

Usually your persistence store is not the file system but a
relational database where you probably don't want to spew text
documents.

Even then, you might have a slicker way of saving the XML
document than by going directly to disk.

The data structure you send across the wire perhaps shouldn't be
as verbose as the one you save to disk.

The state of W3C XML Schema binding support

The following table shows a sampling of web services
implementations together with the XML Schema binding components they
use, plus how those components customize the bindings between XML
Schema data types and Java classes:

Glue, with Electric XML+, and WebLogic Server, with XMLBeans,
seamlessly allow you to serialize XML interchangeably within Web
services and without. WASP requires some do-it-yourself
to use its XML serializer independent of SOAP. The Axis+Castor
marriage is more of a kludge.

It's also worth mentioning the Java Web
Services Developer Pack 1.3. The JWSDP contains Sun's reference
implementation of the JAX-RPC 1.1
specification for mediating between the Java world and the SOAP/WSDL
worlds. The Java API for XML-based RPC, now in version 1.1, has had
to evolve from its RPC/encoded legacy, but its default bindings do
influence the other SOAP engines listed above.

The JWSDP also contains Sun's implementation of the Java Architecture for XML
Binding (JAXB) v1.0.2, a standards-based attempt at a binding
framework. But even though the JWSDP is Basic Profile-conformant,
there's no real integration between the JAX-RPC and JAXB
implementations. To accomplish what's described in our nave example,
you'll have to wait until the JWSDP implements the 2.0 versions of
the JAX-RPC and JAXB specifications, which at long last are being
coordinated. Final drafts are expected by the end of 2004.