|
Apache SOAP Frequently Asked Questions (FAQ)
Apache SOAP Frequently Asked Questions (FAQ)
I have composed this list of questions partly from my own learning process
and partly by perusing questions from the
SOAP User mailing list.
Corrections and suggestions for new questions are always welcome. Please
forward new questions - preferably with answers! - or errors to the
SOAP Developer mailing list.
See also:
Namespaces
-
What are all these SOAP Namespaces?
SOAP uses a few different namespaces for different elements and
attributes depending on the role that the data item in question
plays in the message formatting, handling and/or encoding.
Looking at the Envelope element of a typical SOAP message, we
see the following namespace declarations:
-
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
-
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
-
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
-
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
where 1) is the SOAP Envelope namespace, 2) is the SOAP Encoding
namespace, 3) is the XML Schema Instance namespace and 4) is the XML Schema
Definition namespace. SOAP defines the first two namespaces
and refers to the second two. These namespaces reflect how all data type
definitions in SOAP are delegated to XML Schema.
The SOAP Envelope
namespace defines the Envelope, Header
and Body element names and the encodingStyle,
actor and mustUnderstand attributes.
The SOAP Encoding namespace defines the Array element and the arrayType
attribute used to encode Vector and Array java objects. This encoding
technique is recommended for any linear list of objects. I.e. Java 2
Collection objects can and probably should use this encoding approach.
The XML Schema Instance namespace defines the type
attribute which identifies the data type of an element.
The XML Schema namespace defines several datatypes used
as values of the xsi:type attribute. Examples
include: int, String, double,
and ur-type.
-
Do I need to use namespaces on my XML data?
The short answer is yes, but only a little.
The long answer is that the serialization
registry is necessarily based on qualified names. Thus, if
you are marshalling/unmarshalling Java objects into XML Elements,
those element names will have to be namespace qualified.
Although it is technically possible to just use one
of the SOAP namespaces, it probably isn't a good idea unless the
element name is actually defined in that namespace
(i.e. defined by the
SOAP specification).
If you already have one or more namespaces, use them. If you
need to generate a new namespace, use something like
urn://acmecorp.com/whatever/ as the URI when you
register an element name. See
Serialization below.
-
What are all those namespace prefixes in my SOAP messages?
Won't they keep validation from working?
The Apache SOAP library will generate namespace prefixes as needed
to make sure that all necessary namespaces are declared. If the
same namespace gets declared twice with two different prefixes,
the qualified names should still match with any namespace aware
software. A qualified name is the combination of the namespace
URI plus the local part of the element name (the part after the
prefix).
<SOAP-ENV:Envelope
...xmlns:acme="urn://acmecorp.com/namespace"...>
...
<ns3:GetData xmlns:ns3="urn://acmecorp.com/namespace">
</ns3:GetData>
...
In this example, the prefix can be "ns3" or "acme". Either way,
it refers to the same namespace and, thus, for any local name,
the same element or attribute.
Serialization
-
How do I send user defined java objects using SOAP?
You need to map the Java object to a SOAP XML Element name. This is
done using an XMLJavaMappingRegistry. Typically, you'll want to
use the derived class SOAPMappingRegistry which, among other things,
supports primitive types, Array and Vector objects, and the ability
to be configured via an XML file (DeploymentDescriptor.xml).
Although not required by the SOAP specification, the Apache library
requires that all XML Elements be namespace qualified via the
QName utility class. You can use (almost) anything for the QName.
You might think of the first piece as a "path", and the second
piece as a "SOAP object." You might want to use something like the
following:
SOAPMappingRegistry smr = new SOAPMappingRegistry();
MyObjectSerialzier myObjSer = new MyObjectSerialzier();
smr.mapTypes( Constants.NS_URI_SOAP_ENC,
new QName("urn://myown.com/objects/", "MyObject"),
Object.class, myObjSer, myObjSer );
Then, when you deploy the service that you are calling, you must
have a mapping entry that looks something like the following:
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="urn://myown.com/objects/" qname="x:MyObject"
javaType="com.myown.objects.MyObject"
java2XMLClassName="com.myown.soap.MyObjectSerializer"
xml2JavaClassName="com.myown.soap.MyObjectSerializer"/>
On the server side, all of this (the deployment map) basically says
that when you have a com.myown.objects.POBean object to return to
the caller, you want the SOAP server to use the bean serializer to
translate it into a "urn://myown.com/objects/MyObject" SOAP object
and send it to the client.
One the client side, all of this (the mapTypes() method) says that
when you get a SOAP "urn://myown.com/objects/MyObject" object from
the SOAP server, you would like to use the serializer called myObjSer
to translate the SOAP object into a Java MyObject object.
The main thing you have to do is make sure that the xmlns and qname
values in your deployment descriptor file (or their equivalents in
the GUI) match the values you use in your QName object.
Note, that it is often not necessary to write your own Serializer
or Deserializer. If your class has a get and a set for each attribute
that needs to be marshalled, you can just use the Apache SOAP
BeanSerializer class.
-
What are the different SOAP encoding styles? Which should I use?
The Apache SOAP library uses the SOAP-ENV:encodingStyle
attribute as a lookup qualifier when locating a Serializer
for a Java object or a Deserialzier for an XML element.
The SOAP specification allows the encodingStyle attribute to hold
multiple URIs which denote increasingly general encoding rules.
What isn't defined, however, is how a SOAP processor is to determine
which encoding style to apply. Consequently, the Apache SOAP library
does not support this syntax and will always treat the encodingStyle
attribute value as a single URI reference.
- SOAP Encoding
This encoding style is identified by the SOAP Encoding URI
http://schemas.xmlsoap.org/soap/encoding/ and is
described fully in section 5
of the SOAP specification.
- XMI Encoding
- Literal XML Encoding
-
How do you serialize java.util.Date objects?
Use BeanSerializer. Either add a mapping for date in the deployment
xml file or call SOAPMappingRegistry.mapTypes() in your application.
A more "correct" DateSerializer is planned that serializes using
the ISO date format.
Date objects should be converted to xsd:date or
xsd:timeInstant
to be SOAP compliant. The SOAP spec says, "For simple types, SOAP adopts all the types
found in the section
Built-in datatypes
of the XML Schema Part 2: Datatypes", but not all have been implemented.
-
How do you return a DOM Element from an RPC Call?
The encoding style of a Call return is determined by the encoding style
of the Request. DOM Elements use Literal XML encoding. For example, if a service
accepts one String Parameter and returns an Element,
just set the encoding style for the call to "http://xml.apache.org/xml-soap/literalxml"
and the encoding style for the parameter to "http://schemas.xmlsoap.org/soap/encoding".
Thus, part of your client code would look like:
...
Call call = new Call();
call.setTargetObjectURI("urn:someservice");
call.setMethodName("callmethod");
call.setEncodingStyleURI( Constants.NS_URI_LITERAL_XML );
String strparam = "joebob";
Vector params = new Vector();
params.addElement( new Parameter( "strparam", String.class,
strparam, Constants.NS_URI_SOAP_ENC ) );
...
Service Handlers
-
What is an actor?
Every SOAP message has primary intended recipient. An actor is a
different message recipient that may recieve the message, and
possibly modify it, before forwarding it on to either the next actor
or the final, intended recipient.
SOAP allows Header entries to be addressed to specific
actors with the SOAP-ENV:actor attribute. This attribute
contains the URI that uniquely identifies the actor.
-
What tools are available that use Apache SOAP?
Brought to you by the same folks that brought you UDDI, is the
Web Services Definition Language. WSDL is an XML schema that defines
documents, in XML format, that describe SOAP services. There is an IBM
alphaWorks toolkit that generates Java service client libraries and
service handler skeletons from a WSDL document. See the WSDL
specification
and the IBM toolkit.
-
How do I get the samples installed?
For Tomcat: put the soap.jar and samples classes on the system classpath
(i.e, in $TOMCAT_HOME/classes,lib) rather than in webapps/soap/WEB-INF
-
I am having problems configuring SOAP with Webspere!
Apache SOAP has worked under every version of WebSphere from 1.1 to 3.02.
It will, however, work out of the box on WebSphere 3.5 with fixpak 2 applied.
The WebSphere install instructions for that level are part of the current
SOAP kit. You can browse them
online.
Be sure to check the following items:
- Explicitly set the port number that you have exposed the rpcrouter
servlet on. Even if it is default(80), just mention it in the URL as
http://aaa.bbb.ccc.ddd:port/soap/servlet/rpcrouter.
- Verify that xerces is at the start of your path not only by
setting it in the App but also in the websphere configuration
files (admin.config, setupclient.bat).
-
Does Apache SOAP work with Microsoft SOAP?
Yes, but you need to install a patch to the MS SOAP package.
One of the well-known interoperability problems between Apache 2.0
and MS Soap is that MS clients do not send type information with
each parameter, and the Apache soap server will reject such requests.
James Snell has provided a patch adding the typing. It can be found at
SOAP-WRC web site.
|