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