The Novell exteNd Web Services SDK wsdl2java compiler transforms WSDL documents into Java RMI interfaces. This provides Java programmers with a familiar and typed programming model for invoking and implementing Web Services. The client simply uses a stub to invoke the Web Service as if it was a regular Java object in the same address space, and the server implements a servlet base class.
The wsdl2java compiler is typically used when developing Java client programs that need to access an existing Web Service. As WSDL becomes more wide-spread it is expected that standard Internet services will be formalized with a WSDL document. The wsdl2java compiler can also be used when a developer want to provide a Java based implementation of some service defined using WSDL.
This guide to the Novell exteNd Web Services SDK wsdl2java compiler consists of the following sections:
Introduction - a brief primer to WSDL and how it relates to RMI.
Data Types - the data types supported by the wsdl2java compiler.
Faults - how fault messages map to Java exceptions.
In/Out and Result Parameters - support for in/out and out parameters.
Custom Types - how to add new types to the wsdl2java compiler using type mapper.
You can also refer to the wsdl2java man page for a detailed description of the compiler's command line options.
A WSDL document consists of the following major sections:
Types: this section defines data types available to the Web Service. These types are typically defined using XSD.
Message: the messages used to exchange data with a Web Services. Data includes input parameters, return values and faults.
Operation: an operation is an action that can be performed on a Web Service.
Port type: a port type is a collection of operations.
Binding: the binding defines a concrete protocol and data format for some port type.
Port: a port is a binding and a network address. A port is also called an endpoint as it defines the information necessary to access and invoke on a Web Service.
Service: a service finally combines a number of related endpoints.
Most of the concepts in WSDL map to familiar Java concepts:
WSDL | Java |
Types | Types |
Message | Parameters, return values and exceptions |
Operation | Method |
Port type | Interface |
Binding | The transport and protocol used by a Web Service object instance. |
Service | A set of addresses available to a Web Service object instance. |
Table 1: Equivalence of WSDL and Java concepts.
Below is a very simple WSDL document without binding and service information. It defines a simple currency service, which returns the exchange rate between two countries.
<?xml version="1.0"?>
<definitions name="CurrencyService" targetNamespace="http://example.com/currency.wsdl" xmlns:tns="http://example.com/currency.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="GetRateInput"> <part name="country1" element="xsd:string"/> <part name="country2" element="xsd:string"/> </message> <message name="GetRateOutput"> <part name="result" type="xsd:float"/> </message> <portType name="Currency"> <operation name="getRate"> <input message="tns:GetRateInput"/> <output message="tns:GetRateOutput"/> </operation> </portType> </definitions> |
Example 1: WSDL for a simple currency exchange service.
The currency WSDL maps into a simple Java RMI with a single method, as shown below.
import java.rmi.Remote;
import java.rmi.RemoteException; public interface Currency extends Remote { float getRate(String country1, String country2) throws RemoteException; } |
Example 2: Java interface for the simple currency exchange service.
The table below lists the XML data types supported by the wsdl2java compiler and how they map into Java types. These types are defined in the http://www.w3.org/2001/XMLSchema namespace. For details about XML data types, please refer to the specification at the W3C website.
XML Data Type | Java Data Type |
anyType | java.lang.Object |
boolean | boolean |
byte | byte |
base64Binary | byte[] |
hexBinary | byte[] |
dateTime | java.util.Calendar |
integer | java.math.BigInteger |
double | double |
float | float |
int | int |
long | long |
decimal | java.math.BigDecimal |
short | short |
string | java.lang.String |
QName | javax.xml.rpc.namespace.QName |
Table 2: Mapping between XML and Java data types.
The remaining XML Schema simple data types are mapped to Novell exteNd Web Services SDK classes as summarized in Table 3 below:
XML Data Type | Java Data Type |
anyType | java.lang.Object |
anyURI | com.sssw.jbroker.web.xsd.AnyURI |
date | com.sssw.jbroker.web.xsd.Date |
duration | com.sssw.jbroker.web.xsd.Duration |
ENTITIES | com.sssw.jbroker.web.xsd.ENTITIES |
ENTITY | com.sssw.jbroker.web.xsd.ENTITY |
gDay | com.sssw.jbroker.web.xsd.GDay |
gMonth | com.sssw.jbroker.web.xsd.GMonth |
gMonthDay | com.sssw.jbroker.web.xsd.GMonthDay |
gYearDay | com.sssw.jbroker.web.xsd.GYearDay |
ID | com.sssw.jbroker.web.xsd.ID |
IDREF | com.sssw.jbroker.web.xsd.IDREF |
IDREFS | com.sssw.jbroker.web.xsd.IDREFS |
language | com.sssw.jbroker.web.xsd.Language |
Name | com.sssw.jbroker.web.xsd.Name |
NCName | com.sssw.jbroker.web.xsd.NCName |
NegativeInteger | com.sssw.jbroker.web.xsd.NegativeInteger |
NMTOKEN | com.sssw.jbroker.web.xsd.NMTOKEN |
NMTOKENS | com.sssw.jbroker.web.xsd.NMTOKENS |
NonNegativeInteger | com.sssw.jbroker.web.xsd.NonNegativeInteger |
NonPositiveInteger | com.sssw.jbroker.web.xsd.NonPositiveInteger |
NormalizedString | com.sssw.jbroker.web.xsd.NormalizedString |
PositiveInteger | com.sssw.jbroker.web.xsd.PositiveInteger |
Time | com.sssw.jbroker.web.xsd.Time |
Token | com.sssw.jbroker.web.xsd.Token |
UnsignedByte | com.sssw.jbroker.web.xsd.UnsignedByte |
UnsignedInt | com.sssw.jbroker.web.xsd.UnsignedInt |
UnsignedLong | com.sssw.jbroker.web.xsd.UnsignedLong |
UnsignedLong | com.sssw.jbroker.web.xsd.UnsignedLong |
Table 3: Mapping between other XML simple types and Java data types.
If the nillable attribute is set to "true" when declaring a simple XML type, the wsdl2java compiler generated Java box types, as summarized in Table 4 below:
XML Nillable Data Type | Java Data Type |
boolean | java.lang.Boolean |
byte | java.lang.Byte |
double | java.lang.Double |
float | java.lang.Float |
int | java.lang.Integer |
long | java.lang.Long |
short | java.lang.Short |
Table 4: Mapping between XML nillable types and Java data types.
The data types defined in the SOAP 1.1. specification are always nillable, which means they get mapped as specified in the table below:
SOAP Encoded Type | Java Data Type |
boolean | java.lang.Boolean |
byte | java.lang.Byte |
double | java.lang.Double |
float | java.lang.Float |
int | java.lang.Integer |
long | java.lang.Long |
short | java.lang.Short |
decimal | java.util.BigDecimal |
base64 | byte[] |
Table 5: Mapping between XML nillable types and Java data types.
Furthermore, the Novell exteNd WSSDK compilers support a number of other XML types, which have been declared in the http://schemas.silverstream.com/jBroker namespace. These types are listed in Table 6 below. Note that interoperability is not guaranteed when using Novell exteNd WSSDK data types, and these can only be used safely when both client and server was developed using Novell exteNd WSSDK.
Novell exteNd WSSDK XML Data Type | Java Data Type |
Class | java.lang.Class |
List | java.util.List |
Long | java.lang.Long |
Map | java.util.Map |
Set | java.util.Set |
Table 6: Mapping between Novell exteNd WSSDK XML types and Java data types.
Also, the wsdl2java compiler supports the SOAP array syntax defined in the WSDL specification. Any built-in or custom types can be used to create an array. Below is an example for string:
<complexType name="ArrayOfString">
<complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/> </restriction> </complexContent> </complexType> |
Example 3: Definition of an array type in WSDL.
Although Novell exteNd WSSDK prefers the above definition for arrays, it also supports a number of alternative definitions to provide more flexible parsing of WSDL documents. The four alternative array definitions shown below are also recognized by the wsdl2java compiler:
<complexType name='ArrayOfString'>
<sequence> <element name='name' type='xsd:string' maxOccurs='unbounded'/> </sequence> </complexType> |
Example 3a: Alternative definition of an array type in WSDL.
<complexType name='ArrayOfString'>
<complexContent> <restriction base='SOAP-ENC:Array'> <sequence> <element name='name' type='xsd:String' maxOccurs='unbounded'/> </sequence> </restriction> </complexContent> </complexType> |
Example 3b: Second alternative definition of an array type in WSDL.
<element name='ArrayOfString'>
<complexType> <element name='name' type='xsd:String' maxOccurs='unbounded'/> </complexType> </element> |
Example 3c: Third alternative definition of an array type in WSDL.
<element name='ArrayOfString'>
<complexType> <sequence> <element name='name' type='xsd:String' maxOccurs='unbounded'/> </sequence> </complexType> </element> |
Example 3d: Fourth alternative definition of an array type in WSDL.
WSDL allows operations to produce fault messages. A fault message maps to a Java exception by converting the fault message parts into properties of an exception Java Bean. A marshaler to serialize and de-serialize the exception Java Bean is also generated.
<?xml version="1.0"?>
<definitions name="NameService" targetNamespace="http://example.com/name.wsdl" xmlns:tns=" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="GetNameInput"> <part name="id" element="xsd:int"/> </message> <message name="GetNameOutput"> <part name="result" type="xsd:string"/> </message> <message name="NameNotFound"> <part name="id" type="xsd:int"/> </message> <portType name="NameService"> <operation name="getRate"> <input message="tns:GetNameInput"/> <output message="tns:GetNameOutput"/> <fault name="NoName" message="tns:NameNotFound"/> </operation> </portType> </definitions> |
Example 4: WSDL for a name service, which has a fault message.
The above WSDL document gets mapped into the following RMI.
import java.rmi.Remote;
import java.rmi.RemoteException; public interface NameService extends Remote { String getName(int id) throws NameNotFound, RemoteException; } |
Example 5: Java interface for the name service.
The NameNotFound
exception is a Java Bean with one bean property for
each part of the message. In addition to generating the exception class,
the wsdl2java compiler also generates a NameNotFoundMarshaler
Java
class to support serialization and de-serialization of exceptions of this type.
public class NameNotFound extends Exception
{ private int_id; public NameNotFound() { } public NameNotFound(int id) { _id = id; } public int getId() { return _id; } public setId(int_id) { _id = id; } } |
Example 6: Generated Java exception for the fault message.
WSDL supports both in/out parameters and parameters with return values. An output message with a single part is normally mapped to a regular return value unless it is also an input parameter or it is specified in the parameterOrder attribute. Output messages with multiple parts are mapped to out parameters. Note that if a part has the name "result" or "return", the wsdl2java compiler will map it into a return value unless the input message also has a corresponding "result" or "return" part.
<?xml version="1.0"?>
<definitions name="InOutService" targetNamespace="http://example.com/inout.wsdl" xmlns:tns="http://example.com/inout.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="Input"> <part name="A" element="xsd:int"/> <part name="B" element="xsd:long"/> </message> <message name="Output"> <part name="A" type="xsd:int"/> </message> <portType name="Service"> <operation name="foo" parameterOrder="B A"> <input message="tns:Input"/> <output message="tns:Output"/> </operation> </portType> </definitions> |
Example 7: WSDL with parameter order and in/out and return parameters.
Since both the input and output messages have an "A" part, this maps into an in/out parameter. Since Java always uses pass-by-value semantics, this concepts is supported by using special holder classes that wrap a Java object or primitive type. There are holders for all types supported natively by Novell exteNd WSSDK, and the wsdl2java compiler automatically generates holders for any other out or in/out types. This example also illustrates the use of the parameterOrder attribute.
import java.rmi.Remote;
import java.rmi.RemoteException; public interface Service extends Remote { void foo(long B, IntHolder A) throws RemoteException; } |
Example 8: Java interface with Holder parameters.
The wsdl2java compiler is fully integrated with the type mapper component of Novell exteNd WSSDK. In order to make a custom type available to the wsdl2java compiler, you must provide a resource called xmlrpc.type.mappings. This resource should be available in the CLASSPATH in order for the compiler to pick it up. The format of this resource is the same as described in the address book example:
# # Address Book Type Library Descriptor # address=addressbook.Address addressbook.AddressMarshaler addressbook.AddressMarshaler urn:AddressBook Address http://www.acme.com/schemas exception=addressbook.NoAddressFound com.sssw.jbroker.web.encoding.BeanMarshaler com.sssw.jbroker.web.encoding.BeanMarshaler urn:AddressBook NoAddressFound http://www.acme.com/schemas
If you run the wsdl2java compiler with the -verbose flag, it will
print out all type mapping resources it loads. An easy way to ensure that
the compiler picks up the xmlrpc.type.mappings file is to place it in the
lib
directory where wssdk.jar
is also located.
The compilers will always include this directory into the CLASSPATH before
running.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.