FAQ
History
PreviousHomeNext Search
Feedback
Divider

Creating Web Service Clients with JAX-RPC

This section shows how to create and run these types of clients:

When you run these client examples, they will access the MyHelloService that you deployed in the preceding section.

Static Stub Client Example

StaticStubHello is a stand-alone program that calls the sayHello and sayGoodbye methods of MyHelloService. It makes this call through a stub, a local object which acts as a proxy for the remote service. Because this stub is created before runtime (by the IDE), it is called a static stub.

StaticStubHello Source Code

Before it can invoke the remote methods on the stub, StaticStubHello performs these steps:

  1. Creates a Stub object named stub:
  2. return (Stub)
    new MyHelloService_Impl().getMyHelloServiceRPCPort();

    The program gets the Stub object by invoking a private method named createProxy. Note that the code in this method is implementation-specific and may not be portable because it relies on the MyHelloService_Impl object. The MyHelloService_Impl class is created by the IDE in when you choose the Generate Client Proxy menu item in Building and Running the StaticStubHello Client.

  3. Casts stub to the service definition interface, MyHelloServiceRPC:
  4. MyHelloServiceRPC hello = (MyHelloServiceRPC)stub;

    A service definition interface declares the methods that a remote client may invoke on the service. In this example, the interface (MyHelloServiceRPC) defines the sayHello and sayGoodbye methods. The IDE creates the MyHelloServiceRPC class file when you choose the Generate Client Proxy menu item. The IDE gets the name MyHelloServiceRPC from the WSDL file, which was created in Generating the Service's Helper Classes and WSDL File. When the IDE created the WSDL file, it constructed the name of the service definition interface by appending RPC to the service name (MyHelloService).

Here is the full source code listing for the StaticStubHello client:

package staticstub;

import javax.xml.rpc.Stub;
import staticstub.MyStaticGenClient.MyHelloService_Impl;
import staticstub.MyStaticGenClient.MyHelloServiceRPC;

public class StaticStubHello {
    public static void main(String[] args) {
        try {
            Stub stub = createProxy();
            MyHelloServiceRPC hello = (MyHelloServiceRPC)stub;
            System.out.println(hello.sayHello("Duke"));
            System.out.println(hello.sayGoodbye("Jake"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    private static Stub createProxy() {
        // Note: MyHelloService_Impl is implementation-specific.
       return (Stub)
       (new MyHelloService_Impl().getMyHelloServiceRPCPort());
    }
} 

Building and Running the StaticStubHello Client

These are the basic steps for building and running the client:

  1. Create the client: NewRight ArrowWeb ServicesRight ArrowWeb Service Client.
  2. Generate the client's runtime classes: Right-click the client node and choose Generate Client Proxy.
  3. Right-click the client program and choose Execute.

The detailed steps follow:

  1. In the Explorer, make sure that the MyHelloService WSDL resides in the helloservice package.
  2. In a previous section, Creating MyHelloService, the IDE generated the WSDL file. Later in this section, the IDE reads the WSDL file for information it needs to create runtime classes for the client.

  3. Right-click the staticstub package and choose FileRight ArrowNewRight ArrowWeb ServicesRight ArrowWeb Service Client.
  4. The Web Service Client pane of the New wizard appears.

  5. In the wizard's Specify Web Service Client pane, do the following:
    1. In the Name field enter MyStatic.
    2. In the Package field, enter staticstub.
    3. For the Create From buttons, choose Local WSDL File.
    4. Click Next.
  6. In the wizard's Select Local WSDL File pane, choose the MyHelloService WSDL of the helloservice package.
  7. Click Finish.
  8. The MyStatic client node appears in the Explorer.

  9. In Explorer, right-click the MyStatic client node and choose Generate Client Proxy.
  10. This action creates the MyStatic$Documents and MyStaticGenClient packages. This example will not use the MyStatic$Document package, which contains JSP pages for testing the service.

    The MyStaticGenClient package contains the stub class, serializer classes, and other helper classes required by the client at runtime. This package also contains the MyHelloServiceRPC and MyHelloService_Impl classes. Because these classes are referenced in the client's source code, they must be generated before the client is compiled. (See the section StaticStubHello Source Code).

  11. Right-click StaticStubHello and choose Execute.
  12. The IDE compiles and runs the program. The Output window should display these lines:

    Hello Duke
    Goodby Jake

    In this example, you've run the StaticStubHello client from within the IDE, which can locate the runtime classes with its default classpath. If you were to run the client outside of the IDE, you'd want to create a JAR file containing the runtime classes of the MyStaticGenClient package.

Dynamic Proxy Client Example

The client in the preceding section used a static stub for the proxy. In contrast, the client example in this section, DynamicProxyHello, calls a remote procedure through a dynamic proxy, an object created at runtime that represents the Web service. Although the source code for the StaticStubHelloClient example relied on an implementation-specific class, but the DynamicProxyHello code does not have this limitation. (However, the DynamicProxyHello client does rely on implementation-specific runtime classes that are generated by the IDE.)

DynamicProxyHello Source Code

The DynamicProxyHello program constructs the dynamic proxy as follows:

  1. Creates a Service object named helloService:
  2. Service helloService =
    serviceFactory.createService(helloWsdlUrl,
    new QName(nameSpaceUri, serviceName));

    A Service object is a factory for proxies. To create the Service object (helloService), the program calls the createService method on another type of factory, a ServiceFactory object.

    The createService method has two parameters, the URL of the WSDL file and a QName object. In this example, the URL of the WSDL file points to the WSDL that has been deployed with MyHelloService:

    http://localhost:80/MyHelloService/MyHelloService?WSDL

    A QName object is a tuple that represents an XML qualified name. The tuple is composed of a namespace URI and the local part of the qualified name. In the QName parameter of the createService invocation, the local part is the service name, MyHelloService.

  3. From helloService, creates a proxy (myProxy) with a type of the service definition interface (MyHelloServiceRPC):
  4. MyHelloServiceRPC myProxy =
    (MyHelloServiceRPC) helloService.getPort(
    new QName(nameSpaceUri, portName),
    MyHelloServiceRPC.class);

    The helloService object is a factory for dynamic proxies. To create myProxy, the program calls the getPort method of helloService. This method has two parameters: a QName object that specifies the port name and a java.lang.Class object for the service definition interface. The port name, MyHelloServiceRPCPort, is specified by the WSDL file.

When the IDE creates the WSDL, it constructs the port name by appending RPCPort to the service name (MyHelloService) that you enter in the Specify Web Service pane of the New wizard (See Creating MyHelloService.) The service definition interface, MyHelloServiceRPC, is created by the IDE when you choose the Generate Client Proxy menu item.

The source code for the DynamicProxyHello client follows:

package dynamicproxy;

import java.net.URL;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import dynamicproxy.MyDynamicGenClient.MyHelloServiceRPC;

public class DynamicProxyHello {
    
    public static void main(String[] args) {
        try {
            
            String UrlString =
            
"http://localhost:80/MyHelloService/MyHelloService?WSDL";
            String nameSpaceUri = "urn:MyHelloService/wsdl";
            String serviceName = "MyHelloService";
            String portName = "MyHelloServiceRPCPort";
            
            URL helloWsdlUrl = new URL(UrlString);
            
            ServiceFactory serviceFactory =
                ServiceFactory.newInstance();
            
            Service helloService =
                serviceFactory.createService(helloWsdlUrl,
                new QName(nameSpaceUri, serviceName));
            
            MyHelloServiceRPC myProxy =
                (MyHelloServiceRPC) helloService.getPort(
                new QName(nameSpaceUri, portName),
                MyHelloServiceRPC.class);
            
            System.out.println(myProxy.sayHello("Buzz"));
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
} 

Building and Running the DynamicProxyHello Client

Before performing the steps in this section, you must first create and deploy the MyHelloService as described in Creating a Web Service with JAX-RPC. The steps for building and running the DynamicProxyHello client are the same as those described in Building and Running the StaticStubHello Client, with the following exceptions:

  1. In the New wizard's Specify Web Service Client pane, enter MyDynamic in the Name field and dynamicproxy in the Package field.
  2. When you execute the DynamicProxyHello client, the Output window should display this line:
  3. Hello Buzz

Dynamic Invocation Interface (DII) Client Example

With the dynamic invocation interface (DII), a client can call a remote procedure even if the signature of the remote procedure or the name of the service are unknown until runtime. In contrast to a static stub or dynamic proxy client, a DII client does not require runtime classes generated by the IDE. However, as you'll see in the following section, the source code for a DII client is more complicated than the code of the other two types of clients.


Note: This example is for advanced users who are familiar with WSDL documents. (See Further Information.)


DIIHello Source Code

The DIIHello program performs these steps:

  1. Creates a Service object.
  2. Service service =
    factory.createService(new QName(qnameService));

    To get a Service object, the program invokes the createService method of a ServiceFactory object. The parameter of the createService method is a QName object that represents the name of the service, MyHelloService. The WSDL file specifies this name as follows:

    <service name="MyHelloService">

  3. From the Service object, creates a Call object:
  4. QName port = new QName(qnamePort);
    Call call = service.createCall(port);

    A Call object supports the dynamic invocation of the remote procedures of a service. To get a Call object, the program invokes the Service object's createCall method. The parameter of createCall is a QName object that represents the service definition interface, MyHelloServiceRPC. In the WSDL file, the name of this interface is designated by the portType element:

    <portType name="MyHelloServiceRPC">

  5. Sets the target endpoint address of the Call object:
  6. call.setTargetEndpointAddress(endpoint);

    This address is the URL of the service. (For a static stub client, the IDE refers to the endpoint address as the SOAP RPC URL.) In the WSDL file, this address is specified by the <soap:address> element:

    <service name="MyHelloService">
    <port name="MyHelloServiceRPCPort"
    binding="tns:MyHelloServiceRPCBinding">
    <soap:address
    location="http://localhost:80/MyHelloService/MyHelloService"/>
    </port>
    </service>

  7. Sets these properties on the Call object:
  8. SOAPACTION_USE_PROPERTY
    SOAPACTION_URI_PROPERTY
    ENCODING_STYLE_PROPERTY

    To learn more about these properties, refer to the SOAP and WSDL documents listed in Further Information.

  9. Specifies the method's return type, name, and parameter:
  10. QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
    call.setReturnType(QNAME_TYPE_STRING);

    call.setOperationName(new QName(BODY_NAMESPACE_VALUE,
    "sayHello"));

    call.addParameter("String_1", QNAME_TYPE_STRING,
    ParameterMode.IN);

    To specify the return type, the program invokes the setReturnType method on the Call object. The parameter of setReturnType is a QName object that represents an XML string type.

    The program designates the method name by invoking the setOperationName method with a QName object that represents sayHello.

    To indicate the method parameter, the program invokes the addParameter method on the Call object. The addParameter method has three arguments: a String for the parameter name (String_1), a QName object for the XML type, and a ParameterMode object to indicate the passing mode of the parameter (IN).

  11. Invokes the remote method on the Call object:
  12. String[] params = { "Murphy" };
    String result = (String)call.invoke(params); 
     

    The program assigns the parameter value (Murphy) to a String array (params) and then executes the invoke method with the String array as an argument.

    Here is the source code for the DIIHello client:

    package dii;

    import javax.xml.rpc.Call;
    import javax.xml.rpc.Service;
    import javax.xml.rpc.JAXRPCException;
    import javax.xml.namespace.QName;
    import javax.xml.rpc.ServiceFactory;
    import javax.xml.rpc.ParameterMode;

    public class DIIHello {

    private static String qnameService = "MyHelloService";
    private static String qnamePort = "MyHelloServiceRPC";
    private static String endpoint =
    "http://localhost:80/MyHelloService/MyHelloService";

    private static String BODY_NAMESPACE_VALUE =
    "urn:MyHelloService/wsdl";
    private static String ENCODING_STYLE_PROPERTY =
    "javax.xml.rpc.encodingstyle.namespace.uri";
    private static String NS_XSD =
    "http://www.w3.org/2001/XMLSchema";
    private static String URI_ENCODING =
    "http://schemas.xmlsoap.org/soap/encoding/";

    public static void main(String[] args) {
    try {

    ServiceFactory factory =
    ServiceFactory.newInstance();
    Service service =
    factory.createService(new QName(qnameService));

    QName port = new QName(qnamePort);

    Call call = service.createCall(port);
    call.setTargetEndpointAddress(endpoint);

    call.setProperty(Call.SOAPACTION_USE_PROPERTY,
    new Boolean(true));
    call.setProperty(Call.SOAPACTION_URI_PROPERTY, "");
    call.setProperty(ENCODING_STYLE_PROPERTY,
    URI_ENCODING);
    QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
    call.setReturnType(QNAME_TYPE_STRING);


    call.setOperationName(new QName(BODY_NAMESPACE_VALUE,
    "sayHello"));
    call.addParameter("String_1", QNAME_TYPE_STRING,
    ParameterMode.IN);
    String[] params = { "Murphy" };

    String res
    ult = (String)call.invoke(params);
    System.out.println(result);

    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }
    }

Building and Running the DIIHello Client

Because a DII client does not require generated runtime classes, the procedures for building and running DIIHello are simple.

  1. Make sure you've followed the instructions in Deploying MyHelloService.
  2. In the Explorer, expand the dii package.
  3. Right-click DIIHello and choose Execute.
  4. The Output window should display this line:

    Hello Murphy

Divider
FAQ
History
PreviousHomeNext Search
Feedback
Divider

All of the material in The J2EE Tutorial for the Sun ONE Platform is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.