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 portTypewsdl:operation applies to only this wsdl:operationFor 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:enableAsyncMappingbinding
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:portTypewsdl:portType: applies to all the wsdl:operations
in the portTypewsdl:operation: applies to only this wsdl:operationExample :
<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 MathUtilExceptionclass
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 MathUtilServiceinstead
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 addinstead
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.