Last Modified: 11/4/2005
1. Declaring Customizations
1.1
External Binding Declaration
1.1.1
Root Binding Element
1.1.2 Child Binding Elements
1.2
Embedded Binding Declarations
2. Standard Customizations
2.1 Global
Customizations
2.2 Package
Customization
2.3 Wrapper Style
2.4 Asynchrony
2.5 The Provider
Interface
2.6 Class
Customization
2.6.1 The Service
Endpoint Interface Class
2.6.2 The
Exception Class
2.6.3 The Service
Class
2.7 Java
Method Customization
2.7.1
Service Endpoint Interface Methods
2.7.2 Port Accessor
Methods in the Service Class
2.8
Java Parameter Customization
2.9
Javadoc Customization
2.10 XML
Schema Customization
2.11
Handler Chain Customization
The JAX-WS 2.0 specification defines standard XML-based
customization for WSDL to Java mapping and to control certain features.
These customizations, or binding declarations, can customize
almost all WSDL components that can be mapped to Java, such as the
service endpoint interface class, method name, parameter name,
exception class, etc. The other important thing you can do with these
binding declarations is control certain features, such as asynchrony,
provider, wrapper style, and additional headers. For example, a client
application can enable asynchrony for a particular operation in a portType
or all operations in a portType
or all portType
operations defined in the WSDL file.
The JAX-RPC 1.1 specification did not define a standard customization archictecture. However JAX-RPC 1.x SI had limited WSDL to Java customization support. It allowed a JAX-RPC 1.x application to:
Define a package where Java artifacts mapped from a WSDL file will be generated.
Customize the package for the value classes mapped from the imported XML schema by the WSDL document.
Customize handler chains.
But these customizations were not portable and could not be used across other JAX-RPC implementions. JAX-WS 2.0 SI provides complete support for all the binding declarations defined by the specification.
All the binding declaration elements live in http://java.sun.com/xml/ns/jaxws
namespace. There are two ways to specify binding declarations. In the
first approach, all binding declarations pertaining to a given WSDL
document are grouped together in a standalone document, called an external
binding file. The second approach consists of embedding binding
declarations directly inside a WSDL document. In either case, the jaxws:bindings
element is used as a container for JAX-WS binding declarations. The jaxws
prefix maps to the http://java.sun.com/xml/ns/jaxws
namespace.
External binding files are semantically equivalent to embedded
binding declarations. When wsimport
processes the WSDL
document for which there is an external binding file, it internalizes
the binding declarations defined in the external binding file on the
nodes in the WSDL document they target using the wsdlLocation
attribute. The embedded binding declarations can exist in a WSDL file
and an external binding file targeting that WSDL, but wsimport
may give an error if, upon embedding the binding declarations defined
in the external binding files, the resulting WSDL document contains
conflicting binding declarations.
The jaxws:bindings
declaration appears as the root of
all other binding declarations. This top-level jaxws:bindings
element must specify the location of the WSDL file as a URI in the
value of wsdlLocation
attribute.
Its important that the wsdlLocation
attribute on the
root jaxws:bindings
declaration is same as the WSDL
location URI given to wscompile
.
<jaxws:bindings
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
jaxws:xmlns="http://java.sun.com/xml/ns/jaxws">
...
</jaxws:bindings>
The root jaxws:bindings
element may contain child jaxws:bindings
elements. In this case the child jaxws:bindings
element
must carry an XPath expression in the node attribute to refer to the
WSDL node it customizes.
Here is an excerpt from an external binding file custom-client.xml
in the external-customize
sample:
<jaxws:bindings
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
jaxws:xmlns="http://java.sun.com/xml/ns/jaxws">
<jaxws:bindings node="wsdl:definitions" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jaxws:package name="external_customize.client"/>
...
</jaxws:bindings>
In this example the child jaxws:bindings
applies
package customization. An XPath expression in the node attribute refers
to the root node of the WSDL document, which is wsdl:definitions
and declares the package external_customize.client
for
all the generated Java classes mapped from the WSDL file.
Embedded binding declarations follow different rules compared to the binding declarations declared in the external binding file. Here are some important facts and rules as defined in the JAX-WS 2.0 specification:
jaxws:bindings
element as a WSDL extension.jaxws:bindings
element is used as a WSDL
extension, it must not have a node attribute.jaxrpc:bindings
.Here's an example of embedded binding declarations in the WSDL AddNumbers.wsdl
from the inline-customize
sample:
<wsdl:portType name="AddNumbersImpl">
<!-- wsdl:portType customizations -->
<jaxws:bindings xmlns:jaxrpc="http://java.sun.com/xml/ns/jaxws">
<!-- rename the generated SEI from AddNumbersImpl to MathUtil -->
<jaxws:class name="MathUtil"/>
...
</jaxws:bindings>
<wsdl:operation name="addNumber">
...
</wsdl:portType>
The above WSDL file excerpt shows the wsdl:portType
customization. jaxws:bindings
appears as extension
element of portType
. It customizes the class name of the
generated service endpoint interface. Without this customization, or by
default, the service endpoint interface class is named after the wsdl:portType
name. The binding declaration jaxws:class
customizes the
generated class to be named MathUtil
instead of AddNumberImpl
.
This section provides the details of all the possible WSDL binding
declarations.
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
xmlns="http://java.sun.com/xml/ns/jaxws">
<package name="external_customize.client"/>
<enableWrapperStyle>true</enableWrapperStyle>
<enableAsyncMapping>false</enableAsyncMapping>
</bindings>
By default wscompile
generates WSDL artifacts in a
package computed from the WSDL targetNamespace
. For
example, a WSDL file with the targetNamespace
http://duke.org
without any package
customization will be mapped to the org.duke
package. To
customize the default package mapping you would use a jaxws:package
customization on the wsdl:definitions
node or it can
directly appear inside the top level bindings element.
An important thing to note is that -p option on commandline
wsimport.sh tool (pacakge attribute on wsimport ant task), overrides
the jaxws:package customization,it also overrides the schema package
customization specified using jaxb schema customization.
For example:
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
xmlns="http://java.sun.com/xml/ns/jaxws">
<package name="external_customize.client">
<javadoc>Mathutil package</javadoc>
</package>
...
or
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions">
<package name="external_customize.client">
<javadoc>Mathutil package</javadoc>
</package>
...
wsimport
by default applies wrapper style rules to the
abstract operation defined in the wsdl:portType
, and if
an operation qualifies the Java method signature is generated
accordingly. Wrapper style Java method generation can be disabled by
using jaxws:enableWrapperStyle
.
jaxws:enableWrapperStyle
can appear on the toplevel
bindings element (with @wsdlLocation attribute), it can also appear on
the following target
nodes:
wsdl:definitions
: global scope, applies to all the wsdl:operations
of all wsdl:portType
attributeswsdl:portType
applies to all the wsdl:operations
in the portType
wsdl:operation
applies to only this wsdl:operation
For example:
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
xmlns="http://java.sun.com/xml/ns/jaxws">
<!-- applies to wsdl:definitions node, that would mean the entire wsdl -->
<enableWrapperStyle>true</enableWrapperStyle>
<!-- wsdl:portType operation customization -->
<bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']">
<!-- change java method name from addNumbers() to add() -->
<enableWrapperStyle>false</enableWrapperStyle>
...
In the example above the wrapper style is disabled for the addNumbers
operation in AddNumbersImpl
portType
.This
is because wsimport
processes this binding in the
following order: first wsdl:operation
, then its parent wsdl:portType
,
and finally wsdl:definitions
. Here wsdl:operation
addNumbers
has this customization disabled so this is what
is applied by wsimport
to generate a bare Java method
signature.
A client application can use the jaxws:enableAsyncMapping
binding
declaration so that wsimport
will generate async polling
and callback operations along with the normal synchronous method when
it compiles a WSDL file.
It has the same target nodes as the wrapper style binding declaration described above in section 2.2.
wsdl:definitions
or toplevel bindings element:
global scope, applies to all the wsdl:operations
of all wsdl:portType
wsdl:portType
: applies to all the wsdl:operations
in the portType
wsdl:operation
: applies to only this wsdl:operation
Example :
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL"
xmlns="http://java.sun.com/xml/ns/jaxws">
<!-- applies to wsdl:definitions node, that would mean the entire wsdl -->
<enableAsyncMapping>false</enableAsyncMapping>
<!-- wsdl:portType operation customization -->
<bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']">
<!-- change java method name from addNumbers() to add() -->
<enableAsyncMapping>true</enableAsyncMapping>
...
In the above example wsimport
will generate async
polling and callback methods for the addNumbers
operation. In the wsdl:definition
node, the async
customization is disabled or false but the wsdl:operation
node has it enabled or true, and so wsimport
generates
the async methods of the wsdl:operation
addNumbers
.
This is how the generated signatures look (annotations are removed from synchronous method for reading simplicity):
//synchronous method
public int addNumbers(int number1, int number2) throws
org.duke.AddNumbersFault_Exception, java.rmi.RemoteException;
//async polling Method
public Response<AddNumbersResponse> addNumbers(int number1, int number2);
//async callback Method
public Future<?> addNumbers(int number1, int number2, AsyncHandler<AddNumbersResponse>);
...
By default the value of jaxws:provider
binding is
false. That is, provider interface generation is disabled. In order to
mark a port as provider interface this binding declaration should refer
to the wsdl:port
node using an XPath expression. Please
note that provider binding declaration applies only when developing a
server starting from a WSDL file.
The generated class for wsdl:portType
, wsdl:fault
,
soap:headerfault
, and wsdl:server
can be
customized using the jaxws:class
binding declaration.
Refer to the external binding declaration file custom-client.xml
in the external-customize
sample.
wscompile
will generate the service endpoint interface
class MathUtil
instead of the default AddNumbersImpl
in this example:
<!-- wsdl:portType customization -->
<bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']">
<!-- change the generated SEI class -->
<class name="MathUtil">
<javadoc>Perform mathematical computations</javadoc>
</class>
wsimport
will generate the MathUtilException
class
instead of the default AddNumbersExeption
in this example:
<!-- change the generated exception class name -->
<bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']/wsdl:fault[@name='AddNumbersException']">
<class name="MathUtilException">
<javadoc>Exception generated during computation</javadoc>
</class>
</bindings>
wsimport
will generate MathUtilService
instead
of the default AddNumbersService
in this example:
<!-- wsdl:service customization -->
<bindings node="wsdl:definitions/wsdl:service[@name='AddNumbersService']">
<!-- change the generated service class -->
<class name="MathUtilService">
<javadoc>Service to perform mathematical computations</javadoc>
</class>
</bindings>
The jaxrpc:method
binding declaration is used to
customize the generated Java method name of a service endpoint
interface and to customize the port accessor method in the generated Service
class. Refer to the external binding declaration file custom-client.xml
in the external-customize
sample.
wsimport
will generate a method named add
instead
of the default addNumbers
in this example:
<!-- wsdl:portType operation customization -->
<bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']">
<!-- change java method name from addNumbers() to add() -->
<method name="add">
<javadoc>Adds the numbers</javadoc>
</method>
...
wsimport
will generate the getMathUtil
port accessor method in the generated Service
class
instead of the default getAddNumbersImplPort
method in
this example:
<!-- change the port accessor method -->
<bindings node="wsdl:definitions/wsdl:service[@name='AddNumbersService']/wsdl:port[@name='AddNumbersImplPort']">
<method name="getMathUtil">
<javadoc>Returns MathUtil port</javadoc>
</method>
</bindings>
The jaxws:parameter
binding declaration is used to
change the parameter name of generated Java methods. It can be used to
change the method parameter of a wsdl:operation
in a wsdl:portType.
Refer to the external
binding declaration file custom-client.xml
of the external-customize
sample.
<bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']">
<!-- rename method parameters-->
<parameter part="definitions/message[@name='addNumbers']/part[@name='parameters']" element="tns:number1" name="num1"/>
...
The above sample renames the default parameter name of the Java
method addNumbers
from number1
to num1
.
An XML schema inlined inside a compiled WSDL file can be customized
by using standard JAXB bindings. These JAXB bindings can live inside
the schema or as the child of a jaxws:bindings
element in
an external binding declaration file:
<jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://duke.org']">
<jaxb:schemaBindings>
<jaxb:package name="fromwsdl.server"/>
</jaxb:schemaBindings>
</jaxws:bindings>
External XML schema files imported by the WSDL file can be customized using a JAXB external binding declaration file:
<jxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="1.0">
<jxb:bindings schemaLocation="http://localhost:8080/jaxws-external-customize/schema1.xsd" node="/xsd:schema">
<jxb:schemaBindings>
<jxb:package name="fromjava.client"/>
</jxb:schemaBindings>
</jxb:bindings>
...
The external JAXB binding declaration file can be passed to wsimport
using the -b
switch. See the JAX-WS tools documentation for
details.
jaxws:bindings
customization can be used to customize
or add
handlers. All that is needed is to inline a handler chain configuration
conforming to JSR 181 Handler Chain configuration schema inside jaxws:bindings
element.
<jaxws:bindingsWhen this customization file is passed on to wsimport tool using -b swith togather with the WSDL, wsimport generates all the artifacts togather with a handler configuration file which has everything inside
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="http://localhost:8080/jaxrpc-fromwsdlhandler/addnumbers?WSDL"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jws="http://www.bea.com/xml/ns/jws"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee">
<jaxws:bindings node="wsdl:definitions">
<jws:handler-chain>
<jws:handler-chain-name>LoggingHandlers</jws:handler-chain-name>
<jws:handler>
<j2ee:handler-name>Logger</j2ee:handler-name>
<j2ee:handler-class>fromwsdlhandler.common.LoggingHandler</j2ee:handler-class>
</jws:handler>
</jws:handler-chain>
</jaxws:bindings>
</jaxws:bindings>
jaxws:bindings
element enclosing the jws:handler-chain
element. It also
add @javax.jws.HandlerChain annotation in the generated SEI class.
JAXWS runtime uses the @HandlerChain annotation from the SEI to find
the handlers that has to be added into the handle chain.Copyright © 2005 Sun Microsystems, Inc. All rights reserved.