The asynchronous style of invocation requires extra stub code for the dedicated asynchronous methods defined on the SEI. This special stub code is not generated by default. To switch on the asynchronous feature and generate the requisite stub code, you must use the mapping customization feature from the WSDL 2.0 specification.
Customization enables you to modify the way the wsdl2java generates stub code. In particular,
it enables you to modify the WSDL-to-Java mapping and to switch on certain features. Here, customization is used to switch on the
asynchronous invocation feature. Customizations are specified using a binding declaration, which you define using a
jaxws:bindings
tag (where the jaxws
prefix is tied to the
http://java.sun.com/xml/ns/jaxws
namespace). There are two ways of specifying a binding
declaration:
When using an external binding declaration the jaxws:bindings
element is defined in a
file separatel from the WSDL contract. You specify the location of the binding declaration file to
wsdl2java when you generate the stub code.
When using an embedded binding declaration you embed the jaxws:bindings
element
directly in a WSDL contract, treating it as a WSDL extension. In this case, the settings in
jaxws:bindings
apply only to the immediate parent element.
The template for a binding declaration file that switches on asynchronous invocations is shown in Example 18.2.
Example 18.2. Template for an Asynchronous Binding Declaration
<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="AffectedWSDL
" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="AffectedNode
"> <enableAsyncMapping>true</enableAsyncMapping> </bindings> </bindings>
Where AffectedWSDL
specifies the URL of the WSDL contract that is affected by this binding
declaration. The AffectedNode
is an XPath value that specifies which node (or nodes) from the
WSDL contract are affected by this binding declaration. You can set AffectedNode
to
wsdl:definitions
, if you want the entire WSDL contract to be affected. The
jaxws:enableAsyncMapping
element is set to true
to enable the
asynchronous invocation feature.
For example, if you want to generate asynchronous methods only for the
GreeterAsync
interface, you can specify
<bindings node="wsdl:definitions/wsdl:portType[@name='GreeterAsync']"> in the preceding binding
declaration.
Assuming that the binding declaration is stored in a file, async_binding.xml
, you generate the
requisite stub files with asynchronous support by entering the following command:
wsdl2java -client -b async_binding.xml hello_world.wsdl
When you run wsdl2java, you specify the location of the binding declaration file using the -b
option.
For more information on wsdl2java see wsdl2java in
You can also embed the binding customization directly into the WSDL document defining the service by placing the
jaxws:bindings
element and its associated
jaxws:enableAsynchMapping
child directly into the WSDL. You also must add a namespace
declaration for the jaxws
prefix.
Example 18.3 shows a WSDL file with an embedded binding declaration that activates the asynchronous mapping for an operation.
Example 18.3. WSDL with Embedded Binding Declaration for Asynchronous Mapping
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" ... xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" ...> ... <wsdl:portType name="GreeterAsync"> <wsdl:operation name="greetMeSometime"> <jaxws:bindings> <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping> </jaxws:bindings> <wsdl:input name="greetMeSometimeRequest" message="tns:greetMeSometimeRequest"/> <wsdl:output name="greetMeSometimeResponse" message="tns:greetMeSometimeResponse"/> </wsdl:operation> </wsdl:portType> ... </wsdl:definitions>
When embedding the binding declaration into the WSDL document you can control the scope affected by the declaration by
changing where you place the declaration. When the declaration is placed as a child of the
wsdl:definitions
element the code generator creates asynchronous methods for all of the operations
defined in the WSDL document. If it is placed as a child of a wsdl:portType
element the code
generator creates asynchronous methods for all of the operations defined in the interface. If it is placed as a child of a
wsdl:operation
element the code generator creates asynchronous methods for only that
operation.
It is not necessary to pass any special options to the code generator when using embedded declarations. The code generator will recognize them and act accordingly.
After generating the stub code in this way, the GreeterAsync
SEI (in the file
GreeterAsync.java
) is defined as shown in
Example 18.4.
Example 18.4. Service Endpoint Interface with Methods for Asynchronous Invocations
package org.apache.hello_world_async_soap_http; import org.apache.hello_world_async_soap_http.types.GreetMeSometimeResponse; ... public interface GreeterAsync { public Future<?> greetMeSometimeAsync( java.lang.String requestType, AsyncHandler<GreetMeSometimeResponse> asyncHandler ); public Response<GreetMeSometimeResponse> greetMeSometimeAsync( java.lang.String requestType ); public java.lang.String greetMeSometime( java.lang.String requestType ); }
In addition to the usual synchronous method, greetMeSometime()
, two asynchronous
methods are also generated for the greetMeSometime operation: