by Arun Gupta
Feb 2004
This white paper explains how to unleash the power of the wscompile
and
wsdeploy
tools that are used to develop, deploy, and invoke a Web Service
using Java APIs for
XML-based RPC (JAX-RPC) 1.1. This is the first part of a two
part series and explains the wscompile
and wsdeploy
tools and the configuration files used by these
tools. The second
part explains the most common scenarios that you may encounter during the
Web Service develop, deploy and invoke cycle and how to achieve them using the wscompile
and wsdeploy
tools.
Web Services are Web-based enterprise applications that use open, XML-based standards and transport protocols to exchange data with calling clients.
JAX-RPC Standard Implementation (SI) provides the wscompile
and wsdeploy
tools
that enable you to develop, deploy, and invoke a Web Service. JAX-RPC SI,
along with wscompile
and wsdeploy
tools, is available
in the Java Web Services Developer
Pack (Java WSDP). The Java WSDP is a free integrated toolkit you can use to build, test and deploy XML applications,
Web Services, and Web applications with the latest Web Services technologies and standards implementations. For fully supported, enterprise-class products incorporating Java Web Services technologies,
Sun Java Studio Enterprise and
Sun Java System Application
Server are recommended.
A JAX-RPC Web Service develop/deploy cycle will use both the wscompile
and
wsdeploy
tools. This involves invoking the wscompile
tool
on a Java interface (a.k.a service endpoint interface in the JAX-RPC
specification) or a WSDL to generate artifacts specified by the JAX-RPC
specification (a.k.a. portable artifacts) and a model file. The model is a JAX-RPC SI specific representation of a
Web Service endpoint or client,
generated from the wscompile,
and generally available as a .xml.gz
file. It stores all the information in the form of internal data structures that allows easier generation of implementation-specific artifacts.
These artifacts are then bundled together in
a WAR format (referred to in this paper as the raw
WAR file) along with a deployment descriptor. The wsdeploy
tool takes this
raw WAR file as an input, processes it and generates a WAR file (referred to in
this paper as the
cooked WAR file) which can then be deployed in a servlet container,
exposing the Web Service and the associated WSDL to clients. Figure 1 shows the
JAX-RPC SI Web Service develop and deploy cycle.
Splitting the develop/deploy cycle between two tools provides a logical
separation between the Web Service development and deployment phases. A raw WAR file will contain
only the portable artifacts during the development phase,
a deployment descriptor required for deploying the Web Service, and a model file
generated by wscompile
. The wsdeploy
tool takes this raw WAR file and generates a cooked
WAR
file ready for deployment, which contains
implementation-specific artifacts. The most commonly used scenarios, along with
mechanisms to achieve those scenarios, are described in section 6.0.
A typical JAX-RPC Web Service invocation cycle will use the wscompile
tool. This involves invoking the wscompile
tool on a WSDL to generate
client-side artifacts specified by the JAX-RPC specification as well as other implementation-specific
artifacts. These artifacts are then used along with the client code to invoke
the Web Service. Figure 2 shows a JAX-RPC SI Web Service invoke cycle.
The wscompile
tool generates various client-side and server-side
artifacts required by the JAX-RPC runtime to develop, deploy, and invoke a Web Service. It is available as a shell script and a batch file in JWSDP_HOME/jaxrpc/bin
,
where JWSDP_HOME
refers to the directory in which the Java WSDP is
installed. Although
the shell script
is used below for illustration purposes, the two scripts
provide identical functionality.
If you run the script in a shell with -help
option, this is what you see:
Usage: wscompile [options] configuration_file where [options] include: -classpath <path> specify where to find input class files -cp <path> same as -classpath <path> -d <directory> specify where to place generated output files -define define a service -f:<features> enable the given features (see below) -features:<features> same as -f:<features> -g generate debugging info -gen same as -gen:client -gen:client generate client artifacts (stubs, etc.) -gen:server generate server artifacts (ties, etc.) -source <version> generate code for the specified JAXRPC SI version. supported versions are: 1.0.1, 1.0.3 and 1.1 (default) -httpproxy:<host>:<port> specify a HTTP proxy server (port defaults to 8080) -import generate interfaces and value types only -keep keep generated files -model <file> write the internal model to the given file -nd <directory> specify where to place non-class generated files -O optimize generated code -s <directory> specify where to place generated source files -verbose output messages about what the compiler is doing -version print version information -mapping <file> write the 109 mapping file to the given file Exactly one of the -import, -define, -gen options must be specified. The -f option requires a comma-separated list of features. Supported features (-f): datahandleronly always map attachments to the DataHandler type documentliteral use document literal encoding rpcliteral use rpc literal encoding explicitcontext turn on explicit service context mapping infix:<name> specify an infix to use for generated ties and serializers infix=<name> same as infix:<name> (not on Windows) jaxbenumtype map anonymous enumeration to its base type. nodatabinding turn off data binding for literal encoding noencodedtypes turn off encoding type information nomultirefs turn off support for multiple references norpcstructures do not generate RPC structures (-import only) novalidation turn off full validation of imported WSDL documents resolveidref resolve xsd:IDREF searchschema search schema aggressively for subtypes serializeinterfaces turn on direct serialization of interface types strict generate code strictly compliant with the JAXRPC 1.1 specification useonewayoperations allow generation of one-way operations wsi enable WSI-Basic Profile features (for document/literal and rpc/literal) unwrap enable unWrapping of document/literal wrapper elements in wsi mode donotoverride donot regenerate the classes donotunwrap disable unWrapping of document/literal wrapper elements in wsi mode (Default) Internal options (unsupported): -Xdebugmodel:<file> write a readable version of the model to a file -Xprintstacktrace print exception stack traces -Xserializable generate value types that implement Serializable interface Examples: wscompile -gen -classpath lib/foo.jar;lib/bar.jar -d generated config.xml wscompile -gen -f:infix:Name -d generated config.xml wscompile -define -f:nodatabinding -f:novalidation config.xml wscompile -import -f:explicitcontext config.xml
The tool operates in either import, define, or gen mode and takes a configuration file as an input. The format of the configuration file, for each of the modes, is defined by a schema, which is explained in section 4.0.
An ant task for the wscompile
tool is also provided along with the tool.
The attributes and elements supported by the ant task are listed below:
<wscompile
fork= "true|false"
base="directory for generated class files"
classpath="classpath" | cp="classpath"
define="true|false"
gen="true|false" |
client="true|false" |
server="true|false"
import="true|false"
features="wscompile-features"
HTTPProxy="proxy host and port"
model="model file name"
mapping="mapping file name"
source="1.0.1"|"1.0.3"|"1.1"(default)
nonClassDir="directory for non-class generated
files"
sourceBase="directory for generated source files"
optimize="true|false"
debug="true|false"
keep="true|false"
verbose="true|false"
version="true|false"
xPrintStackTrace="true|false"
xSerializable="true|false"
xDebugModel="text model file name"
config="tool configuration file
name">
</wscompile>
Attribute | Description | Command line |
fork |
forks the wscompile process into another JVM | n/a |
base |
specify where to place output generated classes | -d |
classpath |
specify where to find input class files | -classpath |
cp |
same as -classpath | -cp |
define |
define a service | -define |
gen |
generate client-side artifacts | -gen |
client |
generate client-side artifacts | -gen:client |
server |
generate server-side artifacts | -gen:server |
import |
generate interfaces and value types only | -import |
features |
comma seperated list of features | -features |
f |
same as -features | -f |
HTTPProxy |
specify a HTTP proxy server (port defaults to 8080) | -httpproxy |
model |
write the internal model file to a given file | -model |
mapping |
write the 109 mapping file to the given file | -mapping |
source |
generate code for the specified JAX-RPC SI version. Supported versions are: 1.0.1, 1.0.3, and 1.1 (default) | -source |
nonClassDir |
specify where to place non-class generated files | -nd |
sourceBase |
specify where to place generated source files | -s |
optimize |
optimize generated code | -O |
keep |
keep generated files | -keep |
debug |
generate debugging info | -g |
verbose |
output messages about what the compiler is doing | -verbose |
version |
print version information | -version |
xPrintStackTrace |
print exception stack traces | -Xprintstacktrace |
xSerializable |
generate value types that implement the Serializable interface | -Xserializable |
xDebugModel |
write a readable version of the model to a file | -Xdebugmodel |
config |
configuration file | configuration file |
The classpath attribute is a path-like
structure and can also be set via nested <classpath>
element. Before this task can be used, a <taskdef>
element
needs to be added to the project as given below:
<taskdef name="wscompile" classname="com.sun.xml.rpc.tools.ant.Wscompile">
<classpath path="${classpath}"/>
</taskdef>
where ${classpath}
is the list of classes required
by the JAX-RPC runtime.
<wscompile
gen="true"
base="${build}"
features="explicitcontext"
classpath="xyz.jar"
debug="true"
config="config.xml">
The above example generates client-side artifacts, stores .class
files in the ${build}
directory,
and maps headers in the WSDL to method parameters using the config.xml
configuration file. The classpath used is xyz.jar
and compiles with debug information on.
<wscompile
import="true"
keep="true"
sourceBase="${source.dir}"
base="${build}"
model="model.xml.gz"
xPrintStackTrace="true"
config="config.xml">
<classpath refid="compile.classpath"/>
</wscompile>
The above example generates service endpoint interfaces and value types for the WSDL specified in config.xml
, stores
.java
files in the ${source.dir}
directory, stores .class
files in the ${build}
directory, and generates model file model.xml.gz
in current
directory. It also prints an exception stack trace if an exception occurs. The classpath is a reference to a
path-like structure compile.classpath,
defined elsewhere
in the build environment.
<wscompile
fork="true"
define="true"
nonClassDir="${wsdl.dir}"
features="documentliteral, useonewayoperations"
config="config.xml"/>
The above example generates a document/literal
WSDL in the ${wsdl.dir}
directory for the service
endpoint interface and implementation specified in config.xml
, and
maps methods with void
return type as one-way operations. This will fork off the compiler using the default
javac
executable.
The configuration file is the primary source of information for the wscompile
tool.
This information is processed in conjunction with the various switches specified
during tool invocation to generate the required artifacts. Let's look at the top level schema
declaration for the configuration file.
<?xml version="1.0"
encoding="UTF-8">
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://java.sun.com/xml/ns/jax-rpc/ri/config"
targetNamespace="http://java.sun.com/xml/ns/jax-rpc/ri/config"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
version="1.0">
The schema begins with the standard XML prolog and then declares the schema in the
namespace defined by targetNamespace
, i.e. http://java.sun.com/xml/ns/jax-rpc/ri/config
.
It also defines several other
convenience namespace prefixes: xsd
, referring to the XML schema namespace,
and tns
, referring to the namespace of the configuration file. This schema also
requires all the locally declared elements to be qualified and attributes to be
unqualified.
The top level element is configuration
and is defined as below:
<xsd:element name="configuration">
<xsd:complexType>
<xsd:sequence>
<xsd:choice>
<xsd:element name="service"
type="tns:serviceType"/>
<xsd:element name="wsdl"
type="tns:wsdlType"/>
<xsd:element name="modelfile"
type="tns:modelfileType"/>
<xsd:element name="j2eeMappingFile"
type="tns:j2eeMappingFileType"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
It must contain one, and only
one, of the elements mentioned above corresponding to the four different ways to feed
service information to the tool. Each different method of feeding the information
requires a different format for the configuration file. Each format permits
multiple modes of the tool (-import
, -define,
and -gen
) to be used along with the
tool. The table below shows how the information is fed to wscompile
and the
corresponding format
of the configuration file. It also correlates the wscompile
modes with each
format.
Element name | How the information is fed to the tool ? | Wscompile permitted modes | ||
-import |
-define |
-gen |
||
service | A service description based on a set of service endpoint interfaces | No | Yes | Yes* |
wsdl | A WSDL document to import and process | Yes | No | Yes |
modelfile | A previously saved model file (generated via -model option
in wscompile ) |
No | No | Yes |
j2eeMappingFile | J2EE mapping information defined by JSR 109 | Yes | No | Yes |
* Only -gen:server
is recommended because
client-side artifacts should be generated starting from the WSDL file exposed
after the service is deployed.
The various formats of the configuration file are explained below. Each section starts with explaining the schema for the configuration file format and then provide an example configuration file for that format.
This format is
used when a service description is defined as a set of Java interfaces,
called "service endpoint interfaces" in the JAX-RPC specification. The schema for
specifying the service
element is given below:
<xsd:complexType name="serviceType">
<xsd:sequence>
<xsd:element name="interface" type="tns:interfaceType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="typeMappingRegistry" type="tns:typeMappingRegistryType" minOccurs="0"/>
<xsd:element name="handlerChains" type="tns:handlerChainsType" minOccurs="0"/>
<xsd:element name="namespaceMappingRegistry" type="tns:namespaceMappingRegistryType" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="targetNamespace" type="xsd:anyURI" use="required"/>
<xsd:attribute name="typeNamespace" type="xsd:anyURI" use="required"/>
<xsd:attribute name="packageName" type="xsd:string" use="required"/>
</xsd:complexType>
The name
attribute is used to identify the service. This required attribute
is used by wscompile tool to:
name
attribute in the wsdl:definitions
element, if
a WSDL
is generated.wsdl:service
in generated WSDL documents, if a WSDL is generated.The targetNamespace
attribute, of the type anyURI
, is used as the target namespace for the
generated WSDL document. This is a required attribute.
The typeNamespace
attribute, of the type anyURI
, is used as the target namespace for the XML
schema embedded in the <types>
section of the generated WSDL document.
This is a required attribute.
The packageName
attribute, of the type string
, specifies the name of the Java package in which
all the artifacts related to this service are generated. This is a required
attribute.
The interface
element, of the type interfaceType
(defined below),
is used to specify a service endpoint interface description. This is an optional
element. Although if you are specifying your service starting from Java, you'll
always have at least one interface
element in your configuration file.
The typeMappingRegistry
element, of the type typeMappingRegistryType
(defined in section 3.5.1), is used to specify the type mapping registry used for all the
interface
s in this service. This is an optional element. When absent, the standard type mapping registry supported by the JAX-RPC runtime
will be used. The standard type mapping supports a set of XML data types defined
in the SOAP 1.1 encoding and XML Schema specifications. The standard type mapping
also specifies the XML mapping for the set of Java types supported by the
JAX-RPC. This element is required if your application needs to support mapping
between XML data types and Java types beyond that addressed by the standard type
mapping specification.
The handlerChains
element, of the type handlerChainsType
(defined
in section 3.5.2), is used to specify the handler chains that will be run on the client and
server for all the interface
s defined in this service.
The namespaceMappingRegistry
element, of the type namespaceMappingRegistryType
(defined in section 3.5.3), is used to define the XML namespace to Java package mapping
information for all the interface
s in this service.
Note that since all the elements are defined in a sequence, they must appear in the exact order as listed in the schema.
Let's look at the other types used to define this section before looking at a sample configuration
file. Here is the schema for the interfaceType
element:
<xsd:complexType name="interfaceType">
<xsd:sequence>
<xsd:element
name="handlerChains"
type="tns:handlerChainsType"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute
name="name"
type="xsd:string"
use="required"/>
<xsd:attribute
name="servantName"
type="xsd:string"/>
<xsd:attribute
name="soapAction"
type="xsd:string"/>
<xsd:attribute
name="soapActionBase"
type="xsd:string"/>
</xsd:complexType>
As mentioned earlier, this element is used when an endpoint definition is based on a service endpoint interface.
The name
attribute, of the type string
, specifies the fully-qualified name of the service
endpoint interface (a Java interface). This is a required attribute.
The servantName
attribute, of the type string
, provides the fully-qualified name of the service
endpoint implementation class. This is an optional attribute.
The soapAction
attribute, of the type string
, specifies the SOAPAction string to use for all
operations in the interface. This is an optional attribute.
The soapActionBase
attribute, of the type string
, specifies the base URI for the SOAPAction
string. The SOAPAction for a given operation will be obtained by appending the
operation name to the value provided here. This attribute is mutually exclusive
of soapAction
. This is an optional attribute.
The handlerChains
element, of the type handlerChainsType
(defined
in section 3.5.2), is used to specify the handler chains that will be run on the client and
server for this service endpoint interface. Handlers defined at the interface
level overrides the handlers defined at service
level.
Let's consider a stock quote Web Service as defined by the service endpoint
interface given below:
package com.example;
public interface StockQuoteProvider extends java.rmi.Remote {
public float getLastTradePrice(String tickerSymbol)
throws java.rmi.RemoteException,
com.example.InvalidTickerException;
public StockQuoteInfo getStockQuote(String tickerSymbol)
throws java.rmi.RemoteException,
com.example.InvalidTickerException;
}
public class InvalidTickerException extends
java.lang.Exception {
protected String tickerSymbol;
public InvalidTickerException(String tickersymbol) {
this.tickersymbol = tickerSymbol }
public String getTickerSymbol() { return tickerSymbol; }
}
A sample configuration file for a service defined by this interface is given below:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<service name="StockQuoteService"
targetNamespace="http://stockquote.org/wsdl"
typeNamespace="http://stockquote.org/types"
packageName="com.example">
<interface
name="com.example.StockQuoteProvider"
servantName="com.example.StockQuoteImpl">
</interface>
</service>
</configuration>
com.example.StockQuoteProvider
is the service endpoint interface class
and com.example.StockQuoteImpl
is the service endpoint implementation class for
the given interface. All the artifacts for this interface are generated in the package com.example
, as specified in the packageName
attribute of service
.
Assuming that StockQuoteInfo
is defined as a JavaBeans
component with accessor
and mutator methods only, the service endpoint interface and service endpoint
implementation class are using all standard classes supported by JAX-RPC. In
this case, there is no need to specify typeMappingRegistry
. Excerpts of the
generated WSDL are shown below:
<definitions
name="StockQuoteService"
targetNamespace="http://stockquote.org/wsdl"
xmlns:tns="http://stockquote.org/wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns2="http://stockquote.org/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
...
<types>
<schema
targetNamespace="http://stockquote.org/types"
xmlns:tns="http://stockquote.org/types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://www.w3.org/2001/XMLSchema">
...
<portType name="StockQuoteProvider">
...
<binding name="StockQuoteProviderBinding"
type="tns:StockQuoteProvider">
...
<service name="StockQuoteService">
<port name="StockQuoteProviderPort"
binding="tns:StockQuoteProviderBinding">
<soap:address
location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
</definitions>
The attributes in this WSDL that are copied from the configuration file are highlighted in bold. The table below shows how the attributes in the WSDL are derived from the configuration file:
Attribute value in WSDL | Relationship with attributes in configuration file |
definitions{name} | Copied from service{name} |
defintions{targetNamespace} | Copied from service{targetNamespace} |
schema{targetNamespace} | Copied from service{typeNamespace} |
portType{name} | Derived from the unqualified class name of the
interface as specified in interface{name} |
binding{name} | Derived from the unqualified class name of the
interface as specified in interface{name} and appending
"Binding" |
service{name} | Copied from service{name} |
port{name} | Derived from the unqualified class name of the interface as specified in
interface{name} and appending "Port" |
The endpoint address for each of the port in the generated WSDL is correctly populated once the WSDL is deployed.
This format is used when a description of a service is defined using an existing WSDL document or client-side artifacts need to be generated from the WSDL. The schema for specifying the service element in this case is given below:
<xsd:complexType name="wsdlType">
<xsd:sequence>
<xsd:element
name="typeMappingRegistry"
type="tns:typeMappingRegistryType"
minOccurs="0"/>
<xsd:element
name="handlerChains"
type="tns:handlerChainsType"
minOccurs="0"/>
<xsd:element
name="namespaceMappingRegistry"
type="tns:namespaceMappingRegistryType"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute
name="location"
type="xsd:anyURI"
use="required"/>
<xsd:attribute
name="packageName"
type="xsd:string"
use="required"/>
</xsd:complexType>
The location
attribute, of the type anyURI
, specifies the URL of the WSDL document. This
document can reside either on the local file system or anywhere on the Internet.
This is a required attribute.
The packageName
attribute, of the type string
, specifies the name of the Java package to use
for artifact generation. This is a required attribute.
The typeMappingRegistry
element, of the type typeMappingRegistryType
(defined in section 3.5.1), is used to specify the type mapping registry used for all the ports in this service.
The handlerChains
element, of the type handlerChainsType
(defined
in section 3.5.2), is used to specify the handler chains that will be run
on the client and server for all the
ports defined in this service.
The namespaceMappingRegistry
element, of the type namespaceMappingRegistryType
(defined
in section 3.5.3), is used to define the XML namespace to Java package mapping information for all the
ports in this service.
If the WSDL resides on the internet, then the -httpproxy
option
may need to be used
with wscompile
if you are behind a firewall.
A sample configuration file for the WSDL generated in the previous step is given below:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<wsdl location="./StockQuoteService.wsdl"
pacakgeName="com.example"/>
</configuration>
This configuration file assumes that StockQuoteService.wsdl
is
available in the current working directory and that wscompile
will generate all
the artifacts in the com.example
package.
A model file is a JAX-RPC SI specific representation of a Web Service endpoint or client,
generated from wscompile,
and generally available as a .xml.gz
file. It stores all the information in terms of internal data structures that allows easier generation of implementation-specific artifacts.
Since wsdeploy
supports only a limited set of switches, most of the switches specified during the
wscompile
stage are stored as part of the model.
This format is used when a description of a service is defined or client-side
artifacts need to be generated from an existing
model file, generated through the -model
option of wscompile
. The schema for specifying the service element in this case is given
below:
<xsd:complexType name="modelfileType">
<xsd:sequence>
</xsd:sequence>
<xsd:attribute
name="location"
type="xsd:anyURI"
use="required"/>
</xsd:complexType>
The location
attribute, of the type anyURI
, specifies the URL of the model file (typically
ending in .xml.gz
). This document can reside on the local file system or
anywhere on the Internet. If the model resides on the Internet, the -httpproxy
option may need to be used with wscompile
if you are behind a
firewall.
A sample configuration file starting from a model file will is given below:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<modelfile location="./model.xml.gz"/>
</configuration>
This configuration file assumes that model.xml.gz
is available
in the current working directory.
A J2EE mapping file contains information that correlates the mapping between the Java interfaces and WSDL definitions. A J2EE deployment tool uses this information along with the WSDL file to generate stubs and ties for the deployed services and service-refs.
This format is used when a description of a service is defined in an existing J2EE mapping file and is used only in the J2EE environment. The schema for specifying the service element in this case is given below:
<xsd:complexType name="j2eeMappingFileType">
<xsd:attribute
name="location"
type="xsd:anyURI"
use="required"/>
<xsd:attribute
name="wsdlLocation"
type="xsd:anyURI"
use="required"/>
</xsd:complexType>
The location
attribute, of the type anyURI
, specifies the URL of the J2EE mapping file.
The wsdlLocation
attribute, of the type anyURI
, specifies the URL of the WSDL file.
A J2EE mapping file or WSDL can reside on the local file system or
anywhere on the Internet. If either resides on the internet, then the -httpproxy
option may need to be used with wscompile
if you are behind a
firewall.
A sample configuration file starting from a J2EE mapping file is given below:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<j2eeMappingFile location="./stock-mapping.xml"
wsdlLocation="StockQuoteService.wsdl"/>
</configuration>
This configuration file assumes that stock-mapping.xml
and StockQuoteService.wsdl
are available in the current working directory.
This section describes the advanced features of the wscompile
tool. The features described here are applicable only to the wscompile
configuration files starting from a service endpoint interface or a WSDL.
It is recommended to use standard JAX-RPC type mapping for develop, deploy and invoke phases of a Web Service. Specifying a custom type mapping renders a Web Service and its client non-portable.
Now let's consider a case where the com.example.StockQuoteInfo
class,
from section 3.1, is not
a JavaBeans component and thus not
supported by the standard JAX-RPC runtime (for instance java.util.Vector
is used
as one of the member variables). We need to associate a type mapping with this
interface which facilitates mapping between Java and XML types. The
schema to specify a type mapping is given below:
<xsd:complexType name="typeMappingRegistryType">
<xsd:sequence>
<xsd:element
name="import"
type="tns:importType"
minOccurs="0"/>
<xsd:element
name="typeMapping"
type="tns:typeMappingType"
minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element
name="additionalTypes"
type="tns:additionalTypesType"
minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
The import
element, of the type importType
(defined below), is a
list of XML schema documents that describe user defined types, usually
describing the schema types used by pluggable serializers.
The typeMapping
element, of the type typeMappingType
(defined
below), is a sequence of type mappings. Note this element has an
"unbounded" cardinality, and thus may appear multiple times, one per
encoding.
The additionalTypes
element, of the type additionalTypesType
(defined below), is a list of additional Java types that should be processed even
if they don't appear in the interfaces for the service. Processing involves generating serializers and deserializers for each class
that is a JavaBeans component and plugging them into the type mapping registry created by the tool to
be used at the runtime. This can happen if the class stored in java.util.Vector
does not appear
in any of the method signatures of the service endpoint interface. Otherwise,
the tool attempts to process only the classes that
appear in the service endpoint interface.
The schema to import a list of schema documents is given below:
<xsd:complexType name="importType">
<xsd:sequence>
<xsd:element
name="schema"
type="tns:schemaType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
The schema
element, of the type schemaType
(defined below), is a
list of schema documents to import.
<xsd:complexType name="schemaType">
<xsd:sequence>
<xsd:attribute
name="namespace"
type="xsd:anyURI"
use="required"/>
<xsd:attribute
name="location"
type="xsd:anyURI"
use="required"/>
</xsd:sequence>
</xsd:complexType>
The namespace
attribute, of the type anyURI
, specifies the namespace that
the document describes. This is a required attribute.
The location
attribute, of the type anyURI
, specifies a URL pointing to
the schema document. This is a required attribute.
Let's consider a case where the schema for java.util.Vector
class is available
in the http://schema.org/java/collections/vector
namespace and at http://stockquote.org/types/vector
. In that case,
the import
element will look like:
<import>
<schema
namespace="http://schema.org/java/collections/vector"
location="http://stockquote.org/types/vector/schema"/>
</import>
The schema to define the type mapping for a particular encoding is given below:
<xsd:complexType name="typeMappingType">
<xsd:sequence>
<xsd:element
name="entry"
type="tns:entryType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute
name="encodingStyle"
type="xsd:anyURI"
use="required"/>
</xsd:complexType>
The entry
element, of the type entryType
(defined below), defines a
list of type mapping entries.
The encodingStyle
element, of the type anyURI
, specifies the URI denoting
the encoding. This is a required attribute and should be set to an empty string
in literal cases.
The schema to define a type mapping for an encoding is given below:
<xsd:complexType name="entryType">
<xsd:sequence>
<xsd:attribute
name="schemaType"
type="xsd:QName"
use="required"/>
<xsd:attribute
name="javaType"
type="xsd:string"
use="required"/>
<xsd:attribute
name="serializerFactory"
type="xsd:string"
use="required"/>
<xsd:attribute
name="deserializerFactory"
type="xsd:string"
use="required"/>
</xsd:sequence>
</xsd:complexType>
The schemaType
attribute, of the type QName
, identifies the name of a
schema type. This is a required attribute.
The javaType
attribute, of the type string
, identifies the fully qualified
name of the corresponding Java class. This is a required attribute.
The serializerFactory
attribute, of the type string
, identifies the
fully qualified name of the serializer factory class
to use
for this type. This is a required attribute. The serializer factory provides a
mechanism to access the serializer which will be able to serialize a Java
representation of java.util.Vector
into an XML representation.
The deserializerFactory
attribute, of the type string
, identifies the
fully qualified name of the
deserializer
factory class to use for this type. This is a required attribute. The
deserializer
factory provides a mechanism to access the deserializer which will be able to
deserialize the XML representation to a Java representation of java.util.Vector
.
Continuing with our example, let's consider a case where the imported schema defines the
XML type for java.util.Vector
class as an element by the name
"vector". Also, let's say the serializer and deserializer factories are
available in com.example.VectorSerializerFactory
and com.example.DeserializerFactory
. In
this case the typeMapping
element is given below:
<typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<entry
schemaType="ns1:vector"
javaType="java.util.Vector"
serializerFactory="com.example.SerializerFactory"
deserializerFactory="com.example.DeserializerFactory"
xmlns:ns1="http://schema.org/java/collections/vector"/>
</typeMapping>
Note that the schemaType
element is from the imported namespace.
Writing these serializer and deserializer factories is out of scope of this
article.
Let's say that the java.util.Vector
class used in our example stores instances of a
class which is a JavaBeans component. Since this class does not
appear in the interface anywhere, the wscompile
tool will not be able to generate
serializers and deserializers for this class. By specifying this class under the
additionalTypes
element, we are instructing the tool to generate the serialization artifacts for
this class.
Here is the schema to specify a list of additional Java types to be processed by the tool:
<xsd:complexType name="additionalTypesType">
<xsd:sequence>
<xsd:element
name="class"
type="tns:classType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
The class
element, of the type classType
(defined below),
identifies a list of classes to be processed
<xsd:complexType name="classType">
<xsd:sequence>
<xsd:attribute
name="name"
type="xsd:string"
use="required"/>
</xsd:sequence>
</xsd:complexType>
The name
element identifies the name of the class to be processed.
In our example, if com.example.StockDailyHighs
is stored in a java.util.Vector
,
the additionalType
element will look like:
<additionalTypes>
<class name="com.example.StockDailyHighs"/>
</additionalTypes>
Aggregating all our type mapping information, the typeMappingRegistry
element is given below:
<typeMappingRegistry>
<import>
<schema
namespace="http://schema.org/java/collections/vector"
location="http://stockquote.org/types/vector/schema"/>
</import>
<typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<entry
schemaType="ns1:vector"
javaType="java.util.Vector"
serializerFactory="com.example.SerializerFactory"
deserializerFactory="com.example.DeserializerFactory"
xmlns:ns1="http://schema.org/java/collections/vector"/>
</typeMapping>
<additionalTypes>
<class name="com.example.StockDailyHighs"/>
</additionalTypes>
</typeMappingRegistry>
Thus the complete configuration file for our example, starting from a service endpoint interface is given below:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<service name="StockQuoteService"
targetNamespace="http://stockquote.org/wsdl"
typeNamespace="http://stockquote.org/types"
packageName="com.example">
<interface
name="com.example.StockQuoteProvider"
servantName="com.example.StockQuoteImpl">
</interface>
<typeMappingRegistry>
<import>
<schema
namespace="http://schema.org/java/collections/vector"
location="http://stockquote.org/types/vector/schema"/>
</import>
<typeMapping
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<entry
schemaType="ns1:vector"
javaType="java.util.Vector"
serializerFactory="com.example.SerializerFactory"
deserializerFactory="com.example.DeserializerFactory"
xmlns:ns1="http://schema.org/java/collections/vector"/>
</typeMapping>
<additionalTypes>
<class name="com.example.StockDailyHighs"/>
</additionalTypes>
</typeMappingRegistry>
</xsd:element>
Although this example starts with a service endpoint interface, the schema given above is also applicable for a configuration file starting from a WSDL.
A SOAP message handler gets access to the SOAP message that
represents an RPC request or response. SOAP message handlers are configured via handler
chains, of the type handlerChainsType
(defined below):
<xsd:complexType name="handlerChainsType">
<xsd:sequence>
<xsd:element
name="chain"
type="tns:chainType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
Each handler chain represents an ordered list of handlers and is defined by the following schema:
<xsd:complexType name="chainType">
<xsd:sequence>
<xsd:element
name="handler"
type="tns:handlerType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute
name="runAt"
type="tns:runAtType"
use="required"/>
<xsd:attribute
name="roles"
type="tns:roleListType"/>
</xsd:complexType>
The runAt
attribute, of the type runAtType
(defined below), specifies whether the chain must run on the client or the server.
This is a required attribute as the user must specify whether the handler chain
needs to be configured on the server or client.
The roles
attribute, of the type roleListType
(defined below),
specifies the SOAP roles for the chain.
The handler
element, of the type handlerType
(defined below), specifies a sequence of handlers that form this chain.
A handler chain is configured to act in the role of one or more
SOAP actors, each actor specified using a URI called SOAP actor name. Here is
the schema to specify a list of SOAP roles for a handler chain, i.e. a list of
URIs
<xsd:simpleType name="roleListType">
<xsd:list
itemType="xsd:anyURI"/>
</xsd:simpleType>
The schema for a handler description is given below:
<xsd:complexType name="handlerType">
<xsd:sequence>
<xsd:element
name="property"
type="tns:propertyType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute
name="className"
type="xsd:string"
use="required"/>
<xsd:attribute
name="headers"
type="tns:headerListType"/>
</xsd:complexType>
The className
attribute, of the type string
, provides the fully-qualified name of the handler
class. This is a required attribute.
The headers
attribute, of the type headerListType
(defined below),
identifies the list of header names consumed by this handler. This is an
optional attribute. The headers specified in this attribute are available in
the handler via HandlerInfo.getHeaders
method (shown in the
example below). The headers understood by a handler may be hard-coded within the
handler as well. The decision of whether to specify the headers in the
configuration file or hard-coding them in the handler, is dictated by the
application design.
The property
element, of the type propertyType
(defined below),
defines the initialization properties for this handler. This element is
optional.
Here is the schema to define a list of header names consumed by a handler, i.e. a list of
QNames
:
<xsd:simpleType name="headerListType">
<xsd:list
itemType="xsd:QName"/>
</xsd:simpleType>
Here is the schema to define an initialization property for a handler:
<xsd:complexType name="propertyType">
<xsd:sequence>
</xsd:sequence>
<xsd:attribute
name="name"
type="xsd:string"
use="required"/>
<xsd:attribute
name="value"
type="xsd:string"
use="required"/>
</xsd:complexType>
The name
, of the type string
, attribute defines the name of the property.
The value
, of the type string
, attribute defines the value of the property.
Here is the enumeration of values that the runAt
attribute can
take, and indicates that the handler
can be configured to run either on the client or the server.
<xsd:simpleType name ="runAtType">
<xsd:restriction
base="xsd:string">
<xsd:enumeration
value="client"/>
<xsd:enumeration
value="server"/>
</xsd:restriction>
</xsd:simpleType>
Continuing with our example, let's consider a case where the client sends an encrypted
request to an endpoint and the endpoint decrypts the request before processing it.
This functionality can be easily achieved by plugging in handlers on the client and
server. Let's say com.example.StockEncryptHandler
is
configured as client-side handler and com.example.StockDecryptHandler
is configured as server-side handler. The handlerChains
element for the
client-side is given below:
<handlerChains>
<chain runAt="client">
<handler className="com.example.StockEncryptHandler">
<property
name="bit" value="128"/>
</handler>
</chain>
</handlerChains>
The handlerChains
element for the server-side is given
below:
<handlerChains>
<chain runAt="server">
<handler className="com.example.StockDecryptHandler">
<property
name="bit" value="128"/>
</handler>
</chain>
</handlerChains>
The handlerChains
element for the server-side with a header,
that the handler understands, session-id
in the namespace http://echo.org/example
is
given below:
<handlerChains>
<chain runAt="server">
<handler
className="com.example.StockDecryptHandler">
xmlns:ns0="http://echo.org/example"
headers="ns0:session-id"/>
</handler>
</chain>
</handlerChains>
The headers specified in the configuration file above are accessible in the handler code as given below:
public class StockDecryptHandler extends GenericHandler {
private HandlerInfo config;
public void init(HandlerInfo config) {
this.config = config;
}
public javax.xml.namespace.QName getHeaders() {
config.getHeaders();
}
}
Although this example starts with a service endpoint interface, the schema given above is also applicable for a configuration file starting from a WSDL. This schema is also used for adding handlers to the deployment descriptor.
Both client-side and server-side handlers can be configured with this configuration file. However client-side handlers can also be configured programmatically. Here is a code excerpt to register handlers programmatically in the client code:
package com.example;
...
import javax.xml.rpc.Stub;
import java.util.List;
import java.util.Hashtable;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.HandlerChain;
import javax.xml.rpc.handler.HandlerRegistry;
...
// get the port from generated service
StockQuoteService_Impl serviceImpl = new StockQuoteService_Impl();
StockQuoteServicePort stockPort = serviceImpl.getPort(StockQuoteProvider);
// get the handler registry from generated service (always returns a valid
registry)
HandlerRegistry handlerRegistry = serviceImpl.getHandlerRegistry();
// get handler chain from the registry (always returns a valid chain)
List handlerChain = handlerRegistry.getHandlerChain(stockPort);
// create a new HandlerInfo to populate handler data
HandlerInfo handlerInfo = new HandlerInfo();
// set the handler class
handlerInfo.setHandlerClass(StockEncryptHandler);
// populate the properties
Hashtable hashtable = new Hashtable();
hashtable.put("bit", "128");
// set the properties in handler
handlerInfo.setHandlerConfig(hashtable);
// add the handler to handler chain
handlerChain.add(handlerInfo);
Refer to Java Web Services Developer Pack tutorial for an example on how to build and run a handler example.
Namespace mapping enables to specify mapping between XML namespaces to/from Java packages.
The schema to specify namespace mapping is given below:
<xsd:complexType name="namespaceMappingRegistryType">
<xsd:sequence>
<xsd:element
name="namespaceMapping"
type="tns:namespaceMappingType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
The namespaceMapping
element, of the type namespaceMappingType
(defined below), identifies a list of mappings.
Each XML namespace to/from Java package mapping is defined using the following schema:
<xsd:complexType name="namespaceMappingType">
<xsd:sequence>
</xsd:sequence>
<xsd:attribute
name="namespace"
type="xsd:anyURI"
use="required"/>
<xsd:attribute
name="packageName"
type="xsd:string"
use="required"/>
</xsd:complexType>
The namespace
attribute, of the type string
, identifies the namespace name. This is a required
attribute.
The packageName
attribute, of the type string
, identifies the package name. This is a required
attribute.
Let's consider a WSDL with the following <types>
section:
<types>
<schema targetNamespace="http://stockquote.org/types1"
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="tickerSymbol">
<sequence>
<element name="name" type="string"/>
</sequence>
</complexType>
</schema>
<schema targetNamespace="http://stockquote.org/types2"
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="tickerSymbol">
<sequence>
<element name="name" type="string"/>
<element name="company" type="string"/>
</sequence>
</complexType>
</schema>
</types>
In this WSDL excerpt, tickerSymbol
is a complex type defined in
two different namespaces. The tickerSymbol
defined in the http://stockquote.org/types1
namespace only has the ticker symbol. The tickerSymbol
defined in http://stockquote.org/types2
namespace also contains the company name to which this ticker belongs. To ensure
that wscompile
generates corresponding value types for both of these complex
types, we need to specify namespace to package mappings in the configuration file:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<wsdl location="./StockQuoteService.wsdl"
pacakgeName="com.example">
<namespaceMappingRegistry>
<namespaceMapping
namespace="http://stockquote.org/types1"
packageName="com.example.types1"/>
<namespaceMapping
namespace="http://stockquote.org/types2"
packageName="com.example.types2"/>
</namespaceMappingRegistry>
</wsdl>
</configuration>
wscompile
then generates the com.example.types1.TickerSymbol
and com.example.types2.TickerSymbol
with the appropriate member
variables.
Starting from a service endpoint interface, the configuration file is given below:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
<service name="StockQuoteService"
targetNamespace="http://stockquote.org/wsdl"
typeNamespace="http://stockquote.org/types"
packageName="com.example">
<interface
name="com.example.StockQuoteProvider"
servantName="com.example.StockQuoteImpl">
</interface>
<namespaceMappingRegistry>
<namespaceMapping
namespace="http://stockquote.org/types1"
packageName="com.example.types1"/>
<namespaceMapping
namespace="http://stockquote.org/types2"
packageName="com.example.types2"/>
</namespaceMappingRegistry>
</configuration>
Let's say the com.example.types1.TickerSymbol
and com.example.types2.TickerSymbol
value types are used in the service endpoint interface along with other value
types. In this case, the generated WSDL will have a <types>
section with three <schema>
elements, as shown below:
<types>
<schema targetNamespace="http://stockquote.org/types"
xmlns="http://www.w3.org/2001/XMLSchema">
. . . <!-- other declarations -->
</schema>
<schema targetNamespace="http://stockquote.org/types1"
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="tickerSymbol">
<sequence>
<element name="name" type="string"/>
</sequence>
</complexType>
</schema>
<schema targetNamespace="http://stockquote.org/types2"
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="tickerSymbol">
<sequence>
<element name="name" type="string"/>
<element name="company" type="string"/>
</sequence>
</complexType>
</schema>
</types>
All the types from com.example.types1
package are mapped to http://stockquote.org/types1
namespace, all the types from com.example.types2
package are mapped
to http://stockquote.org/types2
namespace, and all other
types are mapped to http://stockquote.org/types
namespace.
The wsdeploy tool is used in conjunction with wscompile
to generate a WAR file
that can be deployed in any servlet container (Tomcat in the case of the Java Web Services Developer
Pack). This tool takes a raw
WAR file
which contains a service endpoint interface, a service endpoint implementation,
any value types, any service-specific
exceptions, a model file, a deployment descriptor (jaxrpc-ri.xml
), and optionally
any other implementation-
specific artifacts.
The tool processes the raw
WAR file and generates an implementation-
specific
cooked
WAR file. This process involves generating serializers, ties,
runtime descriptors, and other artifacts required for a successful Web Service
deployment. It is available as a shell script and a batch file in JWSDP_HOME/jaxrpc/bin
,
where JWSDP_HOME
refers to the directory in which the Java WSDP is
installed. Although
the shell script is used below for illustration purposes, the two scripts provide identical functionality.
If you run the script in a shell, without any options, this is what you see:
error: missing input WAR file Usage: wsdeploy <options> <WAR file> where <options> include: -classpath <path> specify an optional classpath -keep keep temporary files -o <output WAR file> specify where to place the generated WAR file -tmpdir <directory> specify the temporary directory to use -verbose output messages about what the compiler is doing -version print version information -source <version> generate code for the specified JAXRPC SI version. supported versions are: 1.0.1, 1.0.3 and 1.1 (default) The -o option is required. Examples: wsdeploy -o target.war myapp.war
The tool requires a raw
WAR file and generates a cooked
WAR
file.
An ant task for wsdeploy
tool is also provided along with the tool.
The attributes and elements supported by the ant task are listed below:
<wsdeploy
fork= "true|false"
classpath="classpath" | cp="classpath"
outWarFile="output WAR file name"
keep="true|false"
tmpDir="temporary directory name"
verbose="true|false"
version="true|false"
source="1.0.1"|"1.0.3"|"1.1"(default)
inWarFile="input WAR file name">
</wsdeploy>
Attribute | Description | Command line |
fork |
forks the wsdeploy process into another JVM | n/a |
classpath |
specify where to find input class files | -classpath |
keep |
keep generated files | -keep |
outWarFile |
output cooked WAR file name | -o |
inWarFile |
input raw WAR file name | <WAR file> |
tmpDir |
temporary directory to use | -tmpdir |
source |
generate code for the specified JAXRPC SI version. Supported versions are: 1.0.1, 1.0.3 and 1.1 (default) | -source |
verbose |
output messages about what the compiler is doing | -verbose |
version |
print version information | -version |
The classpath attribute is a path-like
structure and can also be set via nested <classpath>
element.
Before this task can be used, a <taskdef>
element needs to be
added to the project as given below:
<taskdef name="wsdeploy" classname="com.sun.xml.rpc.tools.ant.Wsdeploy">
<classpath path="${classpath}"/>
</taskdef>
where ${classpath}
is the list of classes required
by the JAX-RPC runtime.
<wsdeploy
classpath="xyz.jar"
tmpdir="${tmp}"
outWarFile="stock.war"
inWarFile="stock-raw.war"/>
This example processes a raw
WAR file named stock-raw.war
and
generates a cooked
WAR file named stock.war
. The classpath includes
xyz.jar,
and the temporary directory used is ${tmp}
.
<wsdeploy
keep="true"
outWarFile="stock.war"
inWarFile="stock-raw.war">
<classpath refid="compile.classpath"/>
</wsdeploy>
This example processes a raw
WAR file named stock-raw.war
and
generates a cooked
WAR file named stock.war
. The classpath is a reference to a
path-like structure compile.classpath
, defined elsewhere
in the build environment, and the cooked WAR file contains server-side
artifact source code.
<wsdeploy
fork="true"
source="1.0.3"
outWarFile="stock.war"
inWarFile="stock-raw.war">
</wsdeploy>
This example processes a raw
WAR file named stock-raw.war
and
generates a cooked
WAR file named stock.war
compatible
with JAX-RPC version 1.0.3. This will fork off the compiler using the default javac
executable.
The deployment descriptor, jaxrpc-ri.xml
, is bundled in the raw
WAR file and used by wsdeploy
tool to generate the cooked
WAR file. This descriptor provides information to
wsdeploy
required for deploying the Web Service in the web container. Let's look at the top level schema
declaration for the deployment descriptor.
<?xml version="1.0"
encoding="UTF-8"?>
<xsd:schema
targetNamespace="http://java.sun.com/xml/ns/jax-rpc/ri/dd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://java.sun.com/xml/ns/jax-rpc/ri/dd"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
version="1.0">
The schema begins with the standard XML prolog and then declares the schema in the
namespace defined by targetNamespace
, i.e. http://java.sun.com/xml/ns/jax-rpc/ri/dd
.
It also defines other
convenience namespace prefixes: xsd
, referring to the XML schema namespace,
and tns
, referring to the namespace of deployment descriptor. This schema also
requires all locally declared elements to be qualified and attributes to be
unqualified.
The top level element is webServices
, and is defined below:
<xsd:element name="webServices">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="endpoint"
type="tns:endpointType"
minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element name="endpointMapping"
type="tns:endpointMappingType"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="version"
type="xsd:string"
use="required"/>
<xsd:attribute name="targetNamespaceBase"
type="xsd:string"/>
<xsd:attribute name="typeNamespaceBase"
type="xsd:string"/>
<xsd:attribute name="urlPatternBase"
type="xsd:string"/>
</xsd:complexType>
</xsd:element>
The version
attribute, of the type string
, identifies the version number, and is currently
reserved for future purposes. This is a required attribute and it's value is
fixed at "1.0".
The targetNamespaceBase
attribute, of the type string
,
identifies the base URI for the target namespace of the WSDL documents generated for the endpoints that do not
have their own model file.
The typeNamespaceBase
attribute, of the type string
,
is the same as targetNamespaceBase
attribute, but used for the XML Schema documents embedded in the generated WSDL
documents
The urlPatternBase
attribute, of the type string
,
identifies the base URL pattern for all endpoints. It can be overridden by using
endpointMapping
(see below).
For all of the base properties (targetNamespaceBase
, typeNamespaceBase
,
and urlPatternBase
) the value used for a particular endpoint is
given by the base value with the endpoint name appended to it.
The endpoint
element, of the type endpointType
(defined below) defines a sequence of endpoint descriptions.
The endpointMapping
element, of the type endpointMappingType
,
defines a sequence of endpoint mappings.
Each endpoint within a webServices
element is defined using the schema below:
<xsd:complexType name="endpointType">
<xsd:sequence>
<xsd:element name="handlerChains"
type="tns:handlerChainsType"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name"
type="xsd:string"
use="required"/>
<xsd:attribute name="displayName"
type="xsd:string"/>
<xsd:attribute name="description"
type="xsd:string"/>
<xsd:attribute name="interface"
type="xsd:string"/>
<xsd:attribute name="implementation"
type="xsd:string"/>
<xsd:attribute name="port"
type="xsd:QName"/>
<xsd:attribute name="model"
type="xsd:anyURI"/>
<xsd:attribute name="wsdl"
type="xsd:string"/>
</xsd:complexType>
The name
attribute, of the type string
, defines the name of the endpoint. This is a required
attribute.
The displayName
attribute, of the type string
, defines a human-readable name for the endpoint.
The description
attribute, of the type string
, defines a description of the endpoint.
The interface
attribute, of the type string
, identifies the name of the service endpoint
interface.
The implementation
attribute, of the type string
, identifies the name of the service implementation
class.
The model
attribute, of the type string
, identifies a resource pointing to a model file describing the
endpoint, if any.
The handlerChains
element, of the type handlerChainsType
(defined
above), identifies the handler chains to be used for the endpoint. Refer to
section 4.6 for information on adding handler chains in the deployment descriptor. The only
difference is that in the deployment descriptor, only server-side handlers are
permitted.
Handler chains may be specified in the configuration file during the wscompile
stage or here in the deployment descriptor. It is, however, recommended to
specify the handler chains in the configuration file during the wscompile
stage. If the handler chains are specified in the deployment descriptor, then
they override the handler chains defined in the wscompile
configuration file.
The deployment descriptor also contains endpoint mappings (similar to a servlet-mapping
in
web.xml
) to define a mapping between an endpoint and a URL pattern.
The schema to define an endpoint mapping is given below:
<xsd:complexType name="endpointMappingType">
<xsd:sequence>
</xsd:sequence>
<xsd:attribute name="endpointName"
type="xsd:string"
use="required"/>
<xsd:attribute name="urlPattern"
type="xsd:string"
use="required"/>
</xsd:complexType>
The endpointName
attribute, of the type string
,
identifies the name of the endpoint. This is a
required attribute.
The urlPattern
attribute, of the type string
, defines the URL pattern for the endpoint. This is a
required attribute.
Refer to second part of the white paper for examples of deployment descriptors that define endpoints.
wscompile,
and generally available as a .xml.gz
file. It stores all the information in terms of internal data structures that allows easier generation of implementation-specific artifacts. Since
wsdeploy
supports only a limited set of switches, most of the switches specified during the
wscompile
stage are stored as part of the model.About the author
Arun Gupta is a Staff Engineer in the Java APIs for XML-based RPC (JAX-RPC) development team at Sun Microsystems. Arun has over seven years of experience in the software industry, working in various distributed computing technologies, JavaTM platform, C++, and various web-related technologies. In his current role, Arun is part of the JAX-RPC development team and represents Sun in WS-I Sample Application Working Group. He has been with the JAX-RPC group since its inception and has been a significant contributor in evolving the technology.
JAX-RPC team at Sun Microsystems has provided invaluable input to this white paper.
Send feedback to users@jax-rpc.dev.java.net.