JAX-WS RI 2.1.5 | Users Guide | Tools | JAX-WS RI Extensions | Samples | JAX-WS Community |
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 architecture. 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 implementations. JAX-WS RI 2.1.7 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
wsimport
.
<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:
An embedded binding declaration is
specified by using the
jaxws:bindings
element as a WSDL
extension.
When a
jaxws:bindings
element is used as a WSDL extension, it must not have a node
attribute.
The binding declaration must not
have a child element whose qualified name is
jaxws:bindings
.
A binding declaration embedded in a WSDL can only affect the WSDL element it extends.
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:jaxws="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.
the global customizations are the customizations that applies to
the entire scope of wsdl:definition in the wsdl referenced by the roo
jaxws:bindings@wsdlLocation.
Following customizations have the
global scopes:
<jaxws:package
name="..."/>
<jaxws:enableWrapperStyle/>
<jaxws:enableAsyncMapping/>
These
can appear as direct child of the
root
binding declarations in the external customization file.
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"/> <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.example.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 (package 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
attributes
wsdl: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
jaxws: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
.
jaxws:javadoc customization can be used to specify javadoc text for
java package, class(SEI, Service or Exception class) and on the
methods in SEI and service class. Inorder to do it,it should appear
on the corresponding wsdl nodes.
For package level
javadoc:
<jaxws:package name="xs:string">?
<jaxws:javadoc>xs:string</jaxws:javadoc>?
</jaxws:package>
For
class level javadoc:
<jaxws:class name="xs:string">?
<jaxws:javadoc>xs:string</jaxws:javadoc>?
</jaxws:class>
For
method level javadoc:
<jaxws:method name="xs:string">?
<jaxws:javadoc>xs:string</jaxws:javadoc>?
</jaxws:method>
For
specific samples on javadoc customization for class, refer
SEI,
exception and
service
customization. For javadoc customization on method refer
SEI
method and
service
class port accessor method customization and for package level
customization refer
package
customization.
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.example.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.
Below is a sample JAX-WS binding declaration file with JSR 181 handler chain configuration:
<jaxws:bindings 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/jaxws-fromwsdlhandler/addnumbers?WSDL" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:javaee="http://java.sun.com/xml/ns/javaee"> <jaxws:bindings node="wsdl:definitions"> <javaee:handler-chain> <javaee:handler-chain-name>LoggingHandlers</javaee:handler-chain-name> <javaee:handler> <javaee:handler-name>Logger</javaee:handler-name> <javaee:handler-class>fromwsdlhandler.common.LoggingHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </jaxws:bindings> </jaxws:bindings>
When this customization file is passed on to wsimport tool using -b
switch together with the WSDL, wsimport generates all the artifacts
togather with a handler configuration file which has everything
inside
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.