You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Glen Mazza <gl...@verizon.net> on 2007/07/10 00:38:33 UTC

Re: [CONF] Apache CXF 2.0 Documentation: Developing a Consumer (page edited)

Oops...sorry, forgot to select the "minor edit, don't send email"
option.

Glen

Am Montag, den 09.07.2007, 15:33 -0700 schrieb confluence@apache.org:
> Page Edited : CXF20DOC : Developing a Consumer 
> Developing a Consumer has been edited by Glen Mazza (Jul 09, 2007). 
> 
> (View changes) 
> 
> Content:
> Developing a Consumer with CXF
> Generating the Stub Code
> The starting point for developing a service consumer (or client) in
> CXF is a WSDL contract, complete with port type, binding, and service
> definitions. You can then use the wsdl2java utility to generate the
> Java stub code from the WSDL contract. The stub code provides the
> supporting code that is required to invoke operations on the remote
> service.
> For CXF clients, the wsdl2java utility can generate the following
> kinds of code:
> 
>       * Stub code - supporting files for implementing a CXF client.
>       * Client starting point code - sample client code that connects
>         to the remote service and invokes every operation on the
>         remote service.
>       * Ant build file - a build.xml file intended for use with the
>         ant build utility. It has targets for building and for running
>         the sample client application.
> Basic HelloWorld WSDL contract
> Example1 shows the HelloWorld WSDL contract. This contract defines a
> single port type, Greeter, with a SOAP binding, Greeter_SOAPBinding,
> and a service, SOAPService, which has a single port, SoapPort.
> 
> 
> Example 1:HelloWorld WSDL Contract
> <?xml version="1.0" encoding="UTF-8"?>
> <wsdl:definitions name="HelloWorld" targetNamespace="http://apache.org/hello_world_soap_http" 
>     xmlns="http://schemas.xmlsoap.org/wsdl/" 
>     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
>     xmlns:tns="http://apache.org/hello_world_soap_http"
>     xmlns:x1="http://apache.org/hello_world_soap_http/types"
>     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
>     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>     <wsdl:types>
>         <schema targetNamespace="http://apache.org/hello_world_soap_http/types" 
>             xmlns="http://www.w3.org/2001/XMLSchema"
> 	    xmlns:tns="http://apache.org/hello_world_soap_http/types"
>             elementFormDefault="qualified">
> 	    <simpleType name="MyStringType">
> 		<restriction base="string">
> 		    <maxLength value="30" />
> 		</restriction>
> 	    </simpleType>
> 
>             <element name="sayHi">
>                 <complexType/>
>             </element>
>             <element name="sayHiResponse">
>                 <complexType>
>                     <sequence>
>                         <element name="responseType" type="string"/>
>                     </sequence>
>                 </complexType>
>             </element>
>             <element name="greetMe">
>                 <complexType>
>                     <sequence>
>                         <element name="requestType" type="tns:MyStringType"/>
>                     </sequence>
>                 </complexType>
>             </element>
>             <element name="greetMeResponse">
>                 <complexType>
>                     <sequence>
>                         <element name="responseType" type="string"/>
>                     </sequence>
>                 </complexType>
>             </element>
>             <element name="greetMeOneWay">
>                 <complexType>
>                     <sequence>
>                         <element name="requestType" type="string"/>
>                     </sequence>
>                 </complexType>
>             </element>
>             <element name="pingMe">
>                 <complexType/>
>             </element>
>             <element name="pingMeResponse">
>                 <complexType/>
>             </element>
>             <element name="faultDetail">
>                 <complexType>
>                     <sequence>
>                         <element name="minor" type="short"/>
>                         <element name="major" type="short"/>
>                     </sequence>
>                 </complexType>
>             </element>
>         </schema>
>     </wsdl:types>
>     <wsdl:message name="sayHiRequest">
>         <wsdl:part element="x1:sayHi" name="in"/>
>     </wsdl:message>
>     <wsdl:message name="sayHiResponse">
>         <wsdl:part element="x1:sayHiResponse" name="out"/>
>     </wsdl:message>
>     <wsdl:message name="greetMeRequest">
>         <wsdl:part element="x1:greetMe" name="in"/>
>     </wsdl:message>
>     <wsdl:message name="greetMeResponse">
>         <wsdl:part element="x1:greetMeResponse" name="out"/>
>     </wsdl:message>
>     <wsdl:message name="greetMeOneWayRequest">
>         <wsdl:part element="x1:greetMeOneWay" name="in"/>
>     </wsdl:message>
>     <wsdl:message name="pingMeRequest">
>         <wsdl:part name="in" element="x1:pingMe"/>
>     </wsdl:message>
>     <wsdl:message name="pingMeResponse">
>         <wsdl:part name="out" element="x1:pingMeResponse"/>
>     </wsdl:message>		
>     <wsdl:message name="pingMeFault">
>         <wsdl:part name="faultDetail" element="x1:faultDetail"/>
>     </wsdl:message>
>     
>     <wsdl:portType name="Greeter">
>         <wsdl:operation name="sayHi">
>             <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
>             <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
>         </wsdl:operation>
>         
>         <wsdl:operation name="greetMe">
>             <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
>             <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
>         </wsdl:operation>
>         
>         <wsdl:operation name="greetMeOneWay">
>             <wsdl:input message="tns:greetMeOneWayRequest" name="greetMeOneWayRequest"/>
>         </wsdl:operation>
> 
>         <wsdl:operation name="pingMe">
>             <wsdl:input name="pingMeRequest" message="tns:pingMeRequest"/>
>             <wsdl:output name="pingMeResponse" message="tns:pingMeResponse"/>
>             <wsdl:fault name="pingMeFault" message="tns:pingMeFault"/>
>         </wsdl:operation> 
>     </wsdl:portType>
>     <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
>         <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
>         
>         <wsdl:operation name="sayHi">
>             <soap:operation soapAction="" style="document"/>
>             <wsdl:input name="sayHiRequest">
>                 <soap:body use="literal"/>
>             </wsdl:input>
>             <wsdl:output name="sayHiResponse">
>                 <soap:body use="literal"/>
>             </wsdl:output>
>         </wsdl:operation>
>         
>         <wsdl:operation name="greetMe">
>             <soap:operation soapAction="" style="document"/>
>             <wsdl:input name="greetMeRequest">
>                 <soap:body use="literal"/>
>             </wsdl:input>
>             <wsdl:output name="greetMeResponse">
>                 <soap:body use="literal"/>
>             </wsdl:output>
>         </wsdl:operation>
>         
>         <wsdl:operation name="greetMeOneWay">
>             <soap:operation soapAction="" style="document"/>
>             <wsdl:input name="greetMeOneWayRequest">
>                 <soap:body use="literal"/>
>             </wsdl:input>
>         </wsdl:operation>
> 
>         <wsdl:operation name="pingMe">
>             <soap:operation style="document"/>
>             <wsdl:input>
>                 <soap:body use="literal"/>
>             </wsdl:input>
>             <wsdl:output>
>                 <soap:body use="literal"/>
>             </wsdl:output>
>             <wsdl:fault name="pingMeFault">
>                 <soap:fault name="pingMeFault" use="literal"/>
>             </wsdl:fault>
>         </wsdl:operation>
>         
>     </wsdl:binding>
>     <wsdl:service name="SOAPService">
>         <wsdl:port binding="tns:Greeter_SOAPBinding" name="SoapPort">
>             <soap:address location="http://localhost:9000/SoapContext/SoapPort"/>
>         </wsdl:port>
>     </wsdl:service>
> </wsdl:definitions>
> The Greeter port type from Example1 defines the following WSDL
> operations:
> 
>       * sayHi - has a single output parameter, of xsd:string.
>       * greetMe - has an input parameter, of xsd:string, and an output
>         parameter, of xsd:string.
>       * greetMeOneWay - has a single input parameter, of xsd:string.
>         Because this operation has no output parameters, CXF can
>         optimize this call to be a oneway invocation (that is, the
>         client does not wait for a response from the server).
>       * pingMe - has no input parameters and no output parameters, but
>         it can raise a fault exception.
> 
> Example1 also defines a binding, Greeter_SOAPBinding, for the SOAP
> protocol. In practice, the binding is normally generated
> automatically - for example, by running either of the CXF wsdl2soap or
> wsdl2xml utilities. Likewise, the SOAPService service can be generated
> automatically by running the CXF wsdl2service utility.
> 
> 
> Generating the stub code
> After defining the WSDL contract, you can generate client code using
> the CXF wsdl2java utility. Enter the following command at a
> command-line prompt:
> 
> wsdl2java -ant -client -d ClientDir hello_world.wsdl
> 
> 
> Where ClientDir is the location of a directory where you would like to
> put the generated files and
> hello_world.wsdl is a file containing the contract shown in Example1.
> The -ant option generates an ant build.xml file, for use with the ant
> build utility. The -client option generates starting point code for a
> client main() method.
> 
> The preceding wsdl2java command generates the following Java packages:
> 
>       * org.apache.hello_world_soap_http
>         This package name is generated from the
>         http://apache.org/hello_world_soap_http target namespace. All
>         of the WSDL entities defined in this target namespace (for
>         example, the Greeter port type and the SOAPService service)
>         map to Java classes in the corresponding Java package.
>       * org.apache.hello_world_soap_http.types
>         This package name is generated from the
>         http://apache.org/hello_world_soap_http/types target
>         namespace. All of the XML types defined in this target
>         namespace (that is, everything defined in the wsdl:types
>         element of the HelloWorld contract) map to Java classes in the
>         corresponding Java package.
> 
> The stub files generated by the wsdl2java command fall into the
> following categories:
> 
>       * Classes representing WSDL entities (in the
>         org.apache.hello_world_soap_http package) - the following
>         classes are generated to represent WSDL entities: 
>               * Greeter is a Java interface that represents the
>                 Greeter WSDL port type. In JAX-WS terminology, this
>                 Java interface is a service endpoint interface.
>               * SOAPService is a Java class that represents the
>                 SOAPService WSDL service element.
>               * PingMeFault is a Java exception class (extending
>                 java.lang.Exception) that represents the pingMeFault
>                 WSDL fault element.
>       * Classes representing XML types (in the
>         org.apache.hello_world_soap_http.types package) - in the
>         HelloWorld example, the only generated types are the various
>         wrappers for the request and reply messages. Some of these
>         data types are useful for the
>         asynchronous invocation model.
> Implementing a CXF Client
> This section describes how to write the code for a simple Java client,
> based on the WSDL contract from Example1. To implement the client, you
> need to use the following stub classes:
> 
>       * Service class (that is, SOAPService).
>       * Service endpoint interface (that is, Greeter).
> Generated service class
> Example2 shows the typical outline a generated service class,
> ServiceName, which extends the javax.xml.ws.Service base class.
> 
> 
> Example 2:Outline of a Generated Service Class
> public class ServiceName extends javax.xml.ws.Service
> {
>   ...
>   public ServiceName(URL wsdlLocation, QName serviceName) { }
>   
>   public ServiceName() { }
> 
>   public Greeter getPortName() { }
>   .
>   .
>   .
> }
> The ServiceName class in Example2 defines the following methods:
> 
>       * Constructor methods - the following forms of constructor are
>         defined: 
>               * ServiceName(URL wsdlLocation, QName serviceName)
>                 constructs a service object based on the data in the
>                 serviceName service in the WSDL contract that is
>                 obtainable from wsdlLocation.
>               * ServiceName() is the default constructor, which
>                 constructs a service object based on the service name
>                 and WSDL contract that were provided at the time the
>                 stub code was generated (for example, when running the
>                 CeltiXfire wsdl2java command). Using this constructor
>                 presupposes that the WSDL contract remains available
>                 at its original location.
>       * get_PortName_() methods - for every PortName port defined on
>         the ServiceName service, CXF generates a corresponding
>         get_PortName_() method in Java. Therefore, a wsdl:service
>         element that defines multiple ports will generate a service
>         class with multiple get_PortName_() methods.
> Service endpoint interface
> For every port type defined in the original WSDL contract, you can
> generate a corresponding service endpoint interface in Java. A service
> endpoint interface is the Java mapping of a WSDL port type. Each
> operation defined in the original WSDL port type maps to a
> corresponding method in the service endpoint interface. The
> operation's parameters are mapped as follows:
> 
>      1. The input parameters are mapped to method arguments.
>      2. The first output parameter is mapped to a return value.
>      3. If there is more than one output parameter, the second and
>         subsequent output parameters map to method arguments
>         (moreover, the values of these arguments must be passed using
>         Holder types).
> 
> For example, Example3 shows the Greeter service endpoint interface,
> which is generated from the Greeter port type defined in Example1. For
> simplicity, Example3 omits the standard JAXB and JAX-WS annotations.
> 
> 
> Example 3:The Greeter Service Endpoint Interface
> /* Generated by WSDLToJava Compiler. */
> 
> package org.objectweb.hello_world_soap_http;
>   ...
> public interface Greeter
> {
>   public java.lang.String sayHi();
>   
>   public java.lang.String greetMe(java.lang.String requestType);
> 
>   public void greetMeOneWay(java.lang.String requestType);
> 
>   public void pingMe() throws PingMeFault;
> }
> Client main function
> Example4 shows the Java code that implements the HelloWorld client. In
> summary, the client connects to the SoapPort port on the SOAPService
> service and then proceeds to invoke each of the operations supported
> by the Greeter port type.
> 
> 
> Example 4:Client Implementation Code
> package demo.hw.client;
> 
> import java.io.File;
> import java.net.URL;
> import javax.xml.namespace.QName;
> import org.apache.hello_world_soap_http.Greeter;
> import org.apache.hello_world_soap_http.PingMeFault;
> import org.apche.hello_world_soap_http.SOAPService;
> 
> public final class Client {
> 
>   private static final QName SERVICE_NAME = 
>     new QName("http://apache.org/hello_world_soap_http", "SOAPService");
> 
>   private Client()
>   {
>   }
> 
>   public static void main(String args[]) throws Exception
>   {
>     if (args.length == 0)
>     {
>       System.out.println("please specify wsdl");
>       System.exit(1);
>     }
> 
>     URL wsdlURL;
>     File wsdlFile = new File(args[0]);
>     if (wsdlFile.exists())
>     {
>       wsdlURL = wsdlFile.toURL();
>     }
>     else
>     {
>       wsdlURL = new URL(args[0]);
>     }
> 
>     System.out.println(wsdlURL);
>     SOAPService ss = new SOAPService(wsdlURL, SERVICE_NAME);
>     Greeter port = ss.getSoapPort();
>     String resp;
> 
>     System.out.println("Invoking sayHi...");
>     resp = port.sayHi();
>     System.out.println("Server responded with: " + resp);
>     System.out.println();
> 
>     System.out.println("Invoking greetMe...");
>     resp = port.greetMe(System.getProperty("user.name"));
>     System.out.println("Server responded with: " + resp);
>     System.out.println();
> 
>     System.out.println("Invoking greetMeOneWay...");
>     port.greetMeOneWay(System.getProperty("user.name"));
>     System.out.println("No response from server as method is OneWay");
>     System.out.println();
> 
>     try {
>       System.out.println("Invoking pingMe, expecting exception...");
>       port.pingMe();
>     } catch (PingMeFault ex) {
>       System.out.println("Expected exception: PingMeFault has occurred.");
>       System.out.println(ex.toString());
>     }
>     System.exit(0);
>   }
> }
> 
> The Client.main() function from Example4 proceeds as follows:</para>
> 
>      1. The CXF runtime is implicitly initialized - that is, provided
>         the CXF runtime classes are loaded. Hence, there is no need to
>         call a special function in order to initialize CXF.
>      2. The client expects a single string argument that gives the
>         location of the WSDL contract for HelloWorld. The WSDL
>         location is stored in wsdlURL.
>      3. A new port object (which enables you to access the remote
>         server endpoint) is created in two steps, as shown in the
>         following code fragment: 
>         SOAPService ss = new SOAPService(wsdlURL, SERVICE_NAME);
>         Greeter port = ss.getSoapPort();
>         
>         To create a new port object, you first create a service object
>         (passing in the WSDL location and service name) and then call
>         the appropriate get PortName () method to obtain an instance
>         of the particular port you need. In this case, the SOAPService
>         service supports only the SoapPort port, which is of Greeter
>         type.
>         
>      4. The client proceeds to call each of the methods supported by
>         the Greeter service endpoint interface.
>      5. In the case of the pingMe() operation, the example code shows
>         how to catch the PingMeFault fault exception.
> Setting Connection Properties with Contexts
> You can use JAX-WS contexts to customize the properties of a client
> proxy. In particular, contexts can be used to modify connection
> properties and to send data in protocol headers. For example, you
> could use contexts to add a SOAP header, either to a request message
> or to a response message. The following types of context are supported
> on the client side:
> 
>       * Request context - on the client side, the request context
>         enables you to set properties that affect outbound messages.
>         Request context properties are applied to a specific port
>         instance and, once set, the properties affect every subsequent
>         operation invocation made on the port, until such time as a
>         property is explicitly cleared. For example, you might use a
>         request context property to set a connection timeout or to
>         initialize data for sending in a header.</para>
>       * Response context - on the client side, you can access the
>         response context to read the property values set by the
>         inbound message from the last operation invocation. Response
>         context properties are reset after every operation invocation.
>         For example, you might access a response context property to
>         read header information received from the last inbound
>         message.
> Setting a request context
> To set a particular request context property,
> <replaceable>ContextPropertyName</replaceable>, to the value,
> PropertyValue, use the code shown in Example4.
> 
> 
> Example 4:Setting a Request Context Property on the Client Side
> // Set request context property.
> java.util.Map<String, Object> requestContext =
>   ((javax.xml.ws.BindingProvider)port).getRequestContext();
> requestContext.put(ContextPropertyName, PropertyValue);
> 
> // Invoke an operation.
> port.SomeOperation();
> You have to cast the port object to javax.xml.ws.BindingProvider in
> order to access the request context. The request context itself is of
> type, java.util.Map<String, Object>, which is a hash map that has keys
> of String and values of arbitrary type. Use java.util.Map.put() to
> create a new entry in the hash map.
> 
> 
> Reading a response context
> To retrieve a particular response context property,
> ContextPropertyName, use the code shown in Example5.
> 
> 
> Example 5:Reading a Response Context Property on the Client Side
> // Invoke an operation.
> port.SomeOperation();
> 
> // Read response context property.
> java.util.Map<String, Object> responseContext =
>   ((javax.xml.ws.BindingProvider)port).getResponseContext();
> PropertyType propValue = (PropertyType) responseContext.get(ContextPropertyName);
> 
> The response context is of type, java.util.Map<String, Object>, which
> is a hash map that has keys of type String and values of an arbitrary
> type. Use java.util.Map.get() to access an entry in the hash map of
> response context properties.
> 
> 
> Supported contexts
> CXF supports the following context properties:
> 
>        Context Property Name
>        Context Property Type
> org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES
> org.apache.cxf.ws.addressing.AddressingProperties
> Asynchronous Invocation Model
> In addition to the usual synchronous mode of invocation, CXF also
> supports two forms of asynchronous invocation, as follows:
> 
>       * Polling approach - in this case, to invoke the remote
>         operation, you call a special method that has no output
>         parameters, but returns a javax.xml.ws.Response instance. The
>         Response object (which inherits from the
>         javax.util.concurrency.Future interface) can be polled to
>         check whether or not a response message has arrived.
>       * Callback approach - in this case, to invoke the remote
>         operation, you call another special method that takes a
>         reference to a callback object (of javax.xml.ws.AsyncHandler
>         type) as one of its parameters. Whenever the response message
>         arrives at the client, the CXF runtime calls back on the
>         AsyncHandler object to give it the contents of the response
>         message.
> 
> Both of these asynchronous invocation approaches are described here
> and illustrated by code examples.
> 
> 
> Contract for asynchronous example
> Example6 shows the WSDL contract that is used for the asynchronous
> example. The contract defines a single port type, GreeterAsync, which
> contains a single operation, greetMeSometime.
> 
> 
> Example 6:HelloWorld WSDL Contract for Asynchronous Example
> <wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
>                   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
>                   xmlns:tns="http://apache.org/hello_world_async_soap_http"
>                   xmlns:x1="http://apache.org/hello_world_async_soap_http/types"
>                   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
>                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>                   targetNamespace="http://apache.org/hello_world_async_soap_http"
>                   name="HelloWorld">
>     <wsdl:types>
>         <schema targetNamespace="http://apache.org/hello_world_async_soap_http/types"
>                 xmlns="http://www.w3.org/2001/XMLSchema"
>                 xmlns:x1="http://apache.org/hello_world_async_soap_http/types"
>                 elementFormDefault="qualified">
>             <element name="greetMeSometime">
>                 <complexType>
>                     <sequence>
>                         <element name="requestType" type="xsd:string"/>
>                     </sequence>
>                 </complexType>
>             </element>
>             <element name="greetMeSometimeResponse">
>                 <complexType>
>                     <sequence>
>                         <element name="responseType" type="xsd:string"/>
>                     </sequence>
>                 </complexType>
>             </element>      
>         </schema>
>     </wsdl:types>
>     <wsdl:message name="greetMeSometimeRequest">
>         <wsdl:part name="in" element="x1:greetMeSometime"/>
>     </wsdl:message>
>     <wsdl:message name="greetMeSometimeResponse">
>         <wsdl:part name="out" element="x1:greetMeSometimeResponse"/>
>     </wsdl:message>
>     <wsdl:portType name="GreeterAsync">
>         <wsdl:operation name="greetMeSometime">
>             <wsdl:input name="greetMeSometimeRequest" message="tns:greetMeSometimeRequest"/>
>             <wsdl:output name="greetMeSometimeResponse" message="tns:greetMeSometimeResponse"/>
>         </wsdl:operation>
>     </wsdl:portType>
>     <wsdl:binding name="GreeterAsync_SOAPBinding" type="tns:GreeterAsync">
>         <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
>         <wsdl:operation name="greetMeSometime">
>             <soap:operation style="document"/>
>             <wsdl:input>
>                 <soap:body use="literal"/>
>             </wsdl:input>
>             <wsdl:output>
>                 <soap:body use="literal"/>
>             </wsdl:output>
>         </wsdl:operation>
>     </wsdl:binding>
>     <wsdl:service name="SOAPService">
>         <wsdl:port name="SoapPort" binding="tns:GreeterAsync_SOAPBinding">
>             <soap:address location="http://localhost:9000/SoapContext/SoapPort"/>
>         </wsdl:port>
>     </wsdl:service>
> </wsdl:definitions>
> Generating the asynchronous stub code
> The asynchronous style of invocation requires extra stub code (for
> example, dedicated asychronous methods defined on the service endpoint
> interface). This special stub code is not generated by default,
> however. 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 utility
> 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
> alternative ways of specifying a binding declaration:
> 
>       * External binding declaration - the jaxws:bindings element is
>         defined in a file separately from the WSDL contract. You
>         specify the location of the binding declaration file to the
>         wsdl2java utility when you generate the stub code.
>       * Embedded binding declaration - you can also 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.
> 
> This section considers only the first approach, the external binding
> declaration. The template for a binding declaration file that switches
> on asynchronous invocations is shown in Example7.
> 
> 
> Example 7:Template for an Asynchronous Binding Declaration
> <bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
>           wsdlLocation="@WSDL_LOCATION@/hello_world_async.wsdl"
>           xmlns="http://java.sun.com/xml/ns/jaxws">
>   <bindings node="wsdl:definitions">
>     <enableAsyncMapping>true</enableAsyncMapping>
>   </bindings>
> </bindings>
> <para>Where AffectedWSDLContract 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 port type, you could 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 can generate the requisite stub files with
> asynchronous support by entering the following wsdl2java command:
> 
> wsdl2java -ant -client -d ClientDir -b async_binding.xml
> hello_world.wsdl
> 
> 
> When you run the wsdl2java command, you specify the location of the
> binding declaration file using the -b option. After generating the
> stub code in this way, the GreeterAsync service endpoint interface (in
> the file GreeterAsync.java) is defined as shown in Example8.
> 
> 
> Example 8:Service Endpoint Interface with Methods for Asynchronous
> Invocations
> /* Generated by WSDLToJava Compiler. */
> package org.apache.hello_world_async_soap_http;
> ...
> import java.util.concurrent.Future;
> import javax.xml.ws.AsyncHandler;
> import javax.xml.ws.Response;
> ...
> public interface GreeterAsync {
> 
>   public Future<?> greetMeSometimeAsync(
>     java.lang.String requestType,
>     AsyncHandler<org.apache.hello_world_async_soap_http.types.GreetMeSometimeResponse> asyncHandler
>   );
> 
>   public Response<org.pache.hello_world_async_soap_http.types.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, as follows:
> 
>       * greetMeSometimeAsync() method with Future<?> return type and
>         an extra javax.xml.ws.AsyncHandler parameter - call this
>         method for the callback approach to asynchronous invocation.
>       * greetMeSometimeAsync() method with
>         Response<GreetMeSometimeResponse> return type - call this
>         method for the polling approach to asynchronous invocation.
> 
> The details of the callback approach and the polling approach are
> discussed in the following subsections.
> 
> 
> Implementing an asynchronous client with the polling approach
> Example9 illustrates the polling approach to making an asynchronous
> operation call. Using this approach, the client invokes the
> operation by calling the special Java method, _OperationName_Async(),
> that returns a javax.xml.ws.Response<T> object, where T is the type of
> the operation's response message. The Response<T> object can be polled
> at a later stage to check whether the operation's response message has
> arrived.
> 
> 
> Example 9:Polling Approach for an Asynchronous Operation Call
> package demo.hw.client;
> 
> import java.io.File;
> import java.util.concurrent.Future;
> 
> import javax.xml.namespace.QName;
> import javax.xml.ws.Response;
> 
> import org.apache.hello_world_async_soap_http.GreeterAsync;
> import org.apache.hello_world_async_soap_http.SOAPService;
> import org.apche.hello_world_async_soap_http.types.GreetMeSometimeResponse;
> 
> public final class Client {
>   private static final QName SERVICE_NAME
>     = new QName("http://objectweb.org/hello_world_async_soap_http", "SOAPService");
> 
>   private Client() {}
> 
>   public static void main(String args[]) throws Exception {
>     ...
>     // Polling approach:
>     Response<GreetMeSometimeResponse> greetMeSomeTimeResp =
>       port.greetMeSometimeAsync(System.getProperty("user.name"));
>       while (!greetMeSomeTimeResp.isDone()) {
>         Thread.sleep(100);
>       }
>       GreetMeSometimeResponse reply = greetMeSomeTimeResp.get();
>       ...
>       System.exit(0);
>   }
> }
> The greetMeSometimeAsync() method invokes the greetMeSometimes
> operation, transmitting the input parameters to the remote service and
> returning a reference to a
> javax.xml.ws.Response<GreetMeSometimeResponse> object. The Response
> class is defined by extending the standard
> java.util.concurrency.Future<T> interface, which is specifically
> designed for polling the outcome of work performed by a concurrent
> thread. There are essentially two basic approaches to polling using
> the Response object:
> 
>       * Non-blocking polling - before attempting to get the result,
>         check whether the response has arrived by calling the
>         non-blocking
>         Response<T>.isDone() method. For example: 
>         Response<GreetMeSometimeResponse> greetMeSomeTimeResp = ...;
>         
>         if (greetMeSomeTimeResp.isDone()) {
>           GreetMeSometimeResponse reply = greetMeSomeTimeResp.get();
>         }
>       * Blocking polling - call Response<T>.get() right away and block
>         until the response arrives (optionally specifying a timeout).
>         For example, to poll for a response, with a 60 second
>         timeout: 
>         Response<GreetMeSometimeResponse> greetMeSomeTimeResp = ...;
>         
>         GreetMeSometimeResponse reply = greetMeSomeTimeResp.get(
>           60L,
>           java.util.concurrent.TimeUnit.SECONDS
>           );
> Implementing an asynchronous client with the callback approach
> An alternative approach to making an asynchronous operation invocation
> is to implement a callback class, by deriving from the
> javax.xml.ws.AsyncHandler interface. This callback class must
> implement a handleResponse() method, which is called by the CXF
> runtime to notify the client that the response has arrived. Example10
> shows an outline of the AsyncHandler interface that you need to
> implement.
> 
> 
> Example10: The javax.xml.ws.AsyncHandler Interface
> package javax.xml.ws;
> 
> public interface AsyncHandler<T>
> {
>   void handleResponse(Response<T> res);
> }
> In this example, a callback class, TestAsyncHandler, is defined as
> shown in Example11.
> 
> 
> Example 11: The TestAsyncHandler Callback Class
> package demo.hw.client;
> 
> import javax.xml.ws.AsyncHandler;
> import javax.xml.ws.Response;
> 
> import org.apache.hello_world_async_soap_http.types.GreetMeSometimeResponse;
> 
> public class TestAsyncHandler implements AsyncHandler<GreetMeSometimeResponse> {
>   private GreetMeSometimeResponse reply;
> 
>   public void handleResponse(Response<GreetMeSometimeResponse> response) {
>     try {
>       reply = response.get();
>     } catch (Exception ex) {
>       ex.printStackTrace();
>     }
>   }
> 
>   public String getResponse() {
>     return reply.getResponseType();
>   }
> }
> The implementation of handleResponse() shown in Example11 simply gets
> the response data and stores it in a member variable, reply. The extra
> getResponse() method is just a convenience method that extracts the
> sole output parameter (that is, responseType) from the response.
> 
> Example12 illustrates the callback approach to making an asynchronous
> operation call. Using this approach, the client invokes the operation
> by calling the special Java method, _OperationName_Async(), that
> returns a java.util.concurrency.Future<?> object and takes an extra
> parameter of AsyncHandler<T>.
> 
> 
> Callback Approach for an Asynchronous Operation Call
> package demo.hw.client;
> 
> import java.io.File;
> import java.util.concurrent.Future;
> 
> import javax.xml.namespace.QName;
> import javax.xml.ws.Response;
> 
> import org.apache.hello_world_async_soap_http.GreeterAsync;
> import org.apache.hello_world_async_soap_http.SOAPService;
> import org.apache.hello_world_async_soap_http.types.GreetMeSometimeResponse;
> 
> public final class Client {
>   private static final QName SERVICE_NAME
>     = new QName("http://apache.org/hello_world_async_soap_http", "SOAPService");
> 
>   private Client() {}
> 
>   public static void main(String args[]) throws Exception {
>     ...
>     // Callback approach
>     TestAsyncHandler testAsyncHandler = new TestAsyncHandler();
>     System.out.println("Invoking greetMeSometimeAsync using callback object...");
>     Future<?> response = port.greetMeSometimeAsync(System.getProperty("user.name"), testAsyncHandler);
>     while (!response.isDone()) {
>       Thread.sleep(100);
>     }
>     resp = testAsyncHandler.getResponse();
>     ...
>     System.exit(0);
>   }
> }
> The Future<?> object returned by greetMeSometimeAsync() can be used
> only to test whether or not a response has arrived yet - for example,
> by calling response.isDone(). The value of the response is only made
> available to the callback object, testAsyncHandler.
> 
> 
> 
> 
> Powered by Atlassian Confluence (Version: 2.2.9 Build:#527 Sep 07,
> 2006) - Bug/feature request
> 
> Unsubscribe or edit your notifications preferences