Web Service Clients

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 Creating a Simple Web Service and Client with JAX-RPC.

Dynamic Proxy Client

This example resides in the <INSTALL>/j2eetutorial14/examples/jaxrpc/dynamicproxy/ directory.

The client in the preceding section uses a static stub for the proxy. In contrast, the client example in this section calls a remote procedure through a dynamic proxy, a class that is created during runtime. Although the source code for the static stub client relies on an implementation-specific class, the code for the dynamic proxy client does not have this limitation.

Coding the Dynamic Proxy Client

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. At runtime, the client gets information about the service by looking up its WSDL. In this example, the URL of the WSDL file points to the WSDL that was deployed with MyHelloService:

    http://localhost:8080/hello-jaxrpc/hello?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. The program creates a proxy (myProxy) with a type of the service endpoint interface (HelloIF):
  4. dynamicproxy.HelloIF myProxy =
    (dynamicproxy.HelloIF)helloService.getPort(
    new QName(nameSpaceUri, portName),
    dynamicproxy.HelloIF.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 endpoint interface (HelloIF). The HelloIF class is generated by wscompile. The port name (HelloIFPort) is specified by the WSDL file.

Here is the listing for the HelloClient.java file, located in the <INSTALL>/j2eetutorial14/examples/jaxrpc/dynamicproxy/src/ directory:

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.HelloIF;

public class HelloClient {

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

            String UrlString = args[0] + "?WSDL";
            String nameSpaceUri = "urn:Foo";
            String serviceName = "MyHelloService";
            String portName = "HelloIFPort";

            System.out.println("UrlString = " + UrlString);
            URL helloWsdlUrl = new URL(UrlString);
            
            ServiceFactory serviceFactory =
                ServiceFactory.newInstance();
            
            Service helloService =
                serviceFactory.createService(helloWsdlUrl, 
                new QName(nameSpaceUri, serviceName));
            
            dynamicproxy.HelloIF myProxy = 
                (dynamicproxy.HelloIF) 
                helloService.getPort(
                new QName(nameSpaceUri, portName), 
                dynamicproxy.HelloIF.class); 

            System.out.println(myProxy.sayHello("Buzz"));

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

Building and Running the Dynamic Proxy Client

Before performing the steps in this section, you must first create and deploy MyHelloService as described in Creating a Simple Web Service and Client with JAX-RPC.

To build and package the client, go to the <INSTALL>/j2eetutorial14/examples/jaxrpc/dynamicproxy/ directory and type the following:

asant build 

The preceding command runs these tasks:

The generate-interface task runs wscompile with the -import option. The wscompile command reads the MyHelloService.wsdl file and generates the service endpoint interface class (HelloIF.class). Although this wscompile invocation also creates stubs, the dynamic proxy client does not use these stubs, which are required only by static stub clients.

The compile-client task compiles the src/HelloClient.java file.

The package-dynamic task creates the dist/client.jar file, which contains HelloIF.class and HelloClient.class.

To run the client, type the following:

asant run 

The client should display the following line:

Hello Buzz 

Dynamic Invocation Interface Client

This example resides in the <INSTALL>/j2eetutorial14/examples/jaxrpc/dii/ directory.

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 is unknown until runtime. In contrast to a static stub or dynamic proxy client, a DII client does not require runtime classes generated by wscompile. However, as you'll see in the following section, the source code for a DII client is more complicated than the code for the other two types of clients.

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

Coding the DII Client

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 endpoint interface, MyHelloServiceRPC. In the WSDL file, the name of this interface is designated by the portType element:

    <portType name="HelloIF">

  5. Sets the service endpoint address on the Call object:
  6. call.setTargetEndpointAddress(endpoint);

    In the WSDL file, this address is specified by the <soap:address> element.

  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 listing for the HelloClient.java file, located in the <INSTALL>/j2eetutorial14/examples/jaxrpc/dii/src/ directory:

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 HelloClient {

    private static String qnameService = "MyHelloService";
    private static String qnamePort = "HelloIF";

    private static String BODY_NAMESPACE_VALUE = 
        "urn:Foo";
    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) {

        System.out.println("Endpoint address = " + args[0]);

        try {
            ServiceFactory factory = 
                ServiceFactory.newInstance();
            Service service = 
                factory.createService(
                new QName(qnameService));
    
            QName port = new QName(qnamePort);
    
            Call call = service.createCall(port);
            call.setTargetEndpointAddress(args[0]);
    
            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 = { "Murph!" };

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

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

Building and Running the DII Client

Before performing the steps in this section, you must first create and deploy MyHelloService as described in Creating a Simple Web Service and Client with JAX-RPC.

To build and package the client, go to the <INSTALL>/j2eetutorial14/examples/jaxrpc/dii/ directory and type the following:

asant build 

This build task compiles HelloClient and packages it into the dist/client.jar file. Unlike the previous client examples, the DII client does not require files generated by wscompile.

To run the client, type this command:

asant run 

The client should display this line:

Hello Murph! 

Application Client

Unlike the stand-alone clients in the preceding sections, the client in this section is an application client. Because it's a J2EE component, an application client can locate a local web service by invoking the JNDI lookup method.

J2EE Application HelloClient Listing

Here is the listing for the HelloClient.java file, located in the <INSTALL>/j2eetutorial14/examples/jaxrpc/appclient/src/ directory:

package appclient;

import javax.xml.rpc.Stub;
import javax.naming.*;

public class HelloClient {

    private String endpointAddress;

    public static void main(String[] args) {

        System.out.println("Endpoint address = " + args[0]);

        try {
            Context ic = new InitialContext();
            MyHelloService myHelloService = (MyHelloService) 
                ic.lookup("java:comp/env/service/MyJAXRPCHello");
            appclient.HelloIF helloPort = 
                myHelloService.getHelloIFPort();
            ((Stub)helloPort)._setProperty
                (Stub.ENDPOINT_ADDRESS_PROPERTY,args[0]);

            System.out.println(helloPort.sayHello("Jake!"));
            System.exit(0);

        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    } 
} 

Building the Application Client

Before performing the steps in this section, you must first create and deploy MyHelloService as described in Creating a Simple Web Service and Client with JAX-RPC.

To build the client, go to the <INSTALL>/j2eetutorial14/examples/jaxrpc/appclient/ directory and type the following:

asant build 

As with the static stub client, the preceding command compiles HelloClient.java and runs wscompile by invoking the generate-stubs target.

Packaging the Application Client

Packaging this client is a two-step process:

  1. Create an EAR file for a J2EE application.
  2. Create a JAR file for the application client and add it to the EAR file.

To create the EAR file, follow these steps:

  1. In deploytool, select FileRight ArrowNewRight ArrowApplication.
  2. Click Browse.
  3. In the file chooser, navigate to <INSTALL>/j2eetutorial14/examples/jaxrpc/appclient.
  4. In the File Name field, enter HelloServiceApp.
  5. Click New Application.
  6. Click OK.

To start the New Application Client wizard, select FileRight ArrowNewRight ArrowApplication Client. The wizard displays the following dialog boxes.

  1. Introduction dialog box
    1. Read the explanatory text for an overview of the wizard's features.
    2. Click Next.
  2. JAR File Contents dialog box
    1. Select the button labeled Create New AppClient Module in Application.
    2. In the combo box below this button, select HelloServiceApp.
    3. In the AppClient Display Name field, enter HelloClient.
    4. Click Edit Contents.
    5. In the tree under Available Files, locate the <INSTALL>/j2eetutorial14/examples/jaxrpc/appclient directory.
    6. Select the build directory.
    7. Click Add.
    8. Click OK.
    9. Click Next.
  3. General dialog box
    1. In the Main Class combo box, select appclient.HelloClient.
    2. Click Next.
    3. Click Finish.

Specifying the Web Reference

When it invokes the lookup method, the HelloClient refers to the web service as follows:

MyHelloService myHelloService = (MyHelloService)
ic.lookup("java:comp/env/service/MyJAXRPCHello"); 

You specify this reference as follows.

  1. In the tree, select HelloClient.
  2. Select the Web Service Refs tab.
  3. Click Add.
  4. In the Coded Name field, enter service/MyJAXRPCHello.
  5. In the Service Interface combo box, select appclient.MyHelloService.
  6. In the WSDL File combo box, select META-INF/wsdl/MyHelloService.wsdl.
  7. In the Namespace field, enter urn:Foo.
  8. In the Local Part field, enter MyHelloService.
  9. In the Mapping File combo box, select mapping.xml.
  10. Click OK.

Deploying and Running the Application Client

To deploy the application client, follow these steps:

  1. Select the HelloServiceApp application.
  2. Select ToolsRight ArrowDeploy.
  3. In the Deploy Module dialog box select the checkbox labeled Return Client JAR.
  4. In the field below the checkbox, enter this directory:
  5. <INSTALL>/j2eetutorial14/examples/jaxrpc/appclient

  6. Click OK.

To run the client follow these steps:

  1. In a terminal window, go to the <INSTALL>/j2eetutorial14/examples/jaxrpc/appclient/ directory.
  2. Type the following on a single line:
  3. appclient -client HelloServiceAppClient.jar
    http://localhost:8080/hello-jaxrpc/hello

The client should display this line:

Hello Jake! 

More JAX-RPC Clients

Other chapters in this book also have JAX-RPC client examples: