Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Remove "Example" texts from examples (makes more Docbook-friendly)

...

Basic HelloWorld WSDL contract

#Example1 The below 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.

Anchor
Example1
Example1

Code Block
titleExample 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 This WSDL 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.

...

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 #Example1the WSDL above. 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.

...

This section describes how to write the code for a simple Java client, based on the WSDL contract from #Example1 above. 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 The below shows the typical outline for a generated service class, ServiceName, which extends the javax.xml.ws.Service base class.

Anchor
Example2
Example2

Code Block
titleExample 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:

...

  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 the below 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.

Anchor
Example3
Example3

Code Block
titleExample 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 Here is 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.

Anchor
Example4
Example4

Code Block
titleExample 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>

...

To set a particular request context property, ContextPropertyName, to the value, PropertyValue, use the code shown in #Example4.here:

Anchor
Example4
Example4

Code Block
titleExample 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();

...

To retrieve a particular response context property, ContextPropertyName, use the code shown in #Example5.here:

Anchor
Example5
Example5

Code Block
titleExample 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);

...

Contract for asynchronous example

#Example6 The following example 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.

Anchor
Example6
Example6

Code Block
titleExample 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>

...

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.next:

Anchor
Example7
Example7

Code Block
titleExample 7:Template for an Asynchronous Binding Declaration
<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          wsdlLocation="<at:var at:name="WSDL_LOCATION" />/hello_world_async.wsdl"
          xmlns="http://java.sun.com/xml/ns/jaxws">
  <bindings node="wsdl:definitions">
    <enableAsyncMapping>true</enableAsyncMapping>
  </bindings>
</bindings>

...

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.below:

Anchor
Example8
Example8

Code Block
titleExample 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
  );
}

...

Implementing an asynchronous client with the polling approach

#Example9 The below sample 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.

Anchor
Example9
Example9

Code Block
titleExample 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);
  }
}

...

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 The following shows an outline of the AsyncHandler interface that you need to implement.

Anchor
Example10
Example10

Code Block
titleExample10: 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 #Example11below.

Anchor
Example11
Example11

Code Block
titleExample 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();
  }
}

...