Download FAQ History |  | API Search Feedback

> ## Creating Web Service Clients with JAX-RPC

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

> - Static stub
> - Dynamic proxy
> - Dynamic invocation interface (DII)

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

> ### Static Stub Client Example

> This example resides in the `<INSTALL>``/jwstutorial12/examples/jaxrpc/staticstub/` directory.

> `HelloClient` is a stand-alone program that calls the `sayHello` method of the `MyHelloService`. It makes this call through a stub, a local object which acts as a proxy for the remote service. Because the stub is created before runtime (by `wscompile`), it is usually called a static stub.

> #### Coding the Static Stub Client

> Before it can invoke the remote methods on the stub the client performs these steps:

> 1. Creates a `Stub` object`:`

> `(Stub)(new MyHelloService_Impl().getHelloIFPort())`

> The code in this method is implementation-specific because it relies on a `MyHelloService_Impl` object, which is not defined in the specifications. The `MyHelloService_Impl` class will be generated by `wscompile` in the following section.

> 2. Sets the endpoint address that the stub uses to access the service:

> `stub._setProperty
> (javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, args[0]);`

> At runtime, the endpoint address is passed to `HelloClient` in `args[0]` as a command-line parameter, which `ant` gets from the `endpoint.address` property in the `build.properties` file.

> 3. Casts `stub` to the service endpoint interface, `HelloIF`:

> `HelloIF hello = (HelloIF)stub;`

> Here is the full source code listing for the `HelloClient.java` file, which is located in the directory `<INSTALL>``/jwstutorial12/examples/jaxrpc/staticstub/src/`:

>     package staticstub;

>     import javax.xml.rpc.Stub;

>     public class HelloClient {

>         private String endpointAddress;

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

>             System.out.println("Endpoint address = " + args[0]);
>             try {
>                 Stub stub = createProxy();
>                 stub._setProperty
>                   (javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
>                    args[0]);
>                 HelloIF hello = (HelloIF)stub;
>                 System.out.println(hello.sayHello("Duke!"));
>             } catch (Exception ex) {
>                 ex.printStackTrace();
>             }
>         }

>         private static Stub createProxy() {
>             // Note: MyHelloService_Impl is implementation-specific.
>             return
>             (Stub) (new MyHelloService_Impl().getHelloIFPort());
>         }
>     }

> #### Building the Static Stub Client

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

> To build and package the client, go to the `<JWSDP_HOME>``/docs/tutorial/examples/jaxrpc/staticstub`/ directory and type the following:

>     ant build

> The preceding command invokes these `ant` tasks:

> - `generate-stubs`
> - `compile-client`
> - `package-client`

> The `generate-stubs` task runs the `wscompile` tool as follows:

>     wscompile -gen:client -d build -classpath build config-wsdl.xml

> This `wscompile` command reads the WSDL file that was installed on Tomcat when the service was deployed. The `wscompile` command generates files based on the information in the WSDL file and on the command-line flags. The `-gen:client` flag instructs `wscompile` to generate the stubs, other runtime files such as serializers, and value types. The `-d` flag tells the tool to write the output to the `build` subdirectory. The tool reads the following `config-wsdl.xml` file, which specifies the location of the WSDL file:

>     <?xml version="1.0" encoding="UTF-8"?>
>     <configuration
>        xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
>       <wsdl location="http://localhost:8080/hello-jaxrpc/
>     hello?WSDL"
>            packageName="staticstub"/>
>     </configuration>

> The `compile-client` task compiles `src/HelloClient.java` and writes the class file to the `build` subdirectory.

> The `package-client` task packages the files created by the ge`nerate-stubs` and `compile-client` tasks into the `dist/client.jar` file. Except for the `HelloClient.class`, all of the files in `client.jar` were created by `wscompile`. Note that `wscompile` generated the `HelloIF.class` based on the information it read from the WSDL file.

> #### Running the Static Stub Client

> To run the `HelloClient` program, type the following:

>     ant run

> The program should display this line:

>     Hello Duke!

> The `ant run` target executes this command:

>     java -classpath <cpath> hello.HelloClient <endpoint-address>

> The classpath includes the `client.jar` file that you created in the preceding section, as well as several JAR files that belong to the Java WSDP. In order to run the client remotely, all of these JAR files must reside on the remote client's computer.

> ### Dynamic Proxy Client Example

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

> The client in the preceding section used 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 relied 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:`

> `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/jaxrpc-hello/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`.

> 2. The program creates a proxy (`myProxy`) with a type of the service endpoint interface (`HelloIF`):

> d`ynamicproxy.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>``/jwstutorial12/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 Web Service with JAX-RPC.

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

>     ant build

> The preceding command runs these tasks:

> - `generate-interface`
> - `compile-client`
> - `package-dynamic`

> 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 c`ompile-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:

>     ant run

> The client should display the following line:

>     Hello Buzz

> ### Dynamic Invocation Interface (DII) Client Example

> This example resides in the `<INSTALL>``/jwstutorial12/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 are 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 of 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.

> `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">`

> 2. From the `Service` object, creates a `Call` object:

> `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">`

> 3. Sets the service endpoint address on the `Call` object:

> `call.setTargetEndpointAddress(endpoint);`

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

> 4. Sets these properties on the `Call` object:

> `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.

> 5. Specifies the method's return type, name, and parameter:

> `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`).

> 6. Invokes the remote method on the `Call` object:

> `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>``/jwstutorial12/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 Web Service with JAX-RPC.

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

>     ant 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:

>     ant run

> The client should display this line:

>     Hello Murph!

> ### More JAX-RPC Client Examples

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

> - Chapter 25 includes a static stub client in the Web tier. See the section, Coffee Break Server.
> - Chapter 24 describes a static stub client that demonstrates authentication. See the section, Basic Authentication with JAX-RPC.
> - Chapter 19 shows how a JSP page can be a static stub client that accesses a remote Web service. See the section, The Example JSP Pages.

> In this chapter, the section Advanced JAX-RPC Examples describes JAX-RPC clients with features such as SOAP message handlers and WS-I compliance.

Download FAQ History |  | API Search Feedback

All of the material in The Java(TM) Web Services Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.