This is a simple example that will show you how to develop a Web Service client and service starting from a Java remote interface (RMI). The development process can roughly be divided into the following steps:The build process is conveniently represented in the
- Write the remote Java interface for the service.
- Compile the interface.
- Create stubs and skeletons using the rmi2soapcompiler.
- Implement the client.
- Implement the server.
- Deploy the server in a servlet container.
- Run the client against the server.
build.sh
andbuild.bat
files, which are included with each example. Before running the build scripts, you need to setup your environment as stated in the README. You can use theenv.bat
,env.sh
, orenv.csh
file to easily set up your build environment.1 Hello Remote Interface
Below is the RMI for the Hello World Application. The Hello interface has one method,sayHello
which takes no parameters and returns a string. The RMI serves as a contract between the object implementation and its clients.package hello; import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote { String sayHello() throws RemoteException; }2 Compiling the Interface
We'll use the target directoryWEB-INF/classes
, since this directory structure is necessary when creating the servlet WAR file later. If the directory doesn't already exist, use the following commands to create it:Then compile the interface using the familiar javac compiler. On UNIX systems:mkdir WEB-INF
cd WEB-INF
mkdir classesOn Windows systems:javac -d WEB-INF/classes Hello.javajavac -d WEB-INF\classes Hello.java3 Generating the SOAP Bindings
Before generating the SOAP bindings, you must have the classes directory available in theCLASSPATH
. Set yourCLASSPATH
as follows (depending on operating system and shell):Also, ensure that the Novell exteNd WSSDK binaries are in yourset CLASSPATH=WEB-INF/classes:$CLASSPATHPATH
. Adapt the below examples to fit the location where you installed Novell exteNd WSSDK on your system. On Unix (bash):On Windows:export PATH=/usr/local/wssdk/bin/solaris;$PATHFinally, you must ensure that the Servlet library is in yourset PATH=C:\wssdk\bin\win32;%PATH%CLASSPATH
. If you're using Tomcat you might do:Run the rmi2soap compiler on theset CLASSPATH=%CLASSPATH%;C:\jakarta-tomcat-4.0.1\lib\servlet.jarHello.class
file to generate the SOAP bindings from the above Java remote interface.The rmi2soap compiler generates the Java code to thermi2soap -d WEB-INF/classes hello.HelloWEB-INF/classes
directory, and compiles the generated Java code to the same directory. The following classes are created in the hello Java package:
Hello_Stub.class // stub _Hello_ServiceSkeleton.class // inheritance based skeleton _Hello_ServiceTieSkeleton.class // delegation based skeleton HelloService.class // service interface HelloServiceImpl.class // service implementation class You can run rmi2soap with the -keep flag if you wish to keep the source files for the stubs and skeletons. Please consult the rmi2soap man page for a detailed description of the command line flags.
4 Implementing the Client
The client implementation uses JNDI to lookup the service object. The service can in turn be used to create a stub for the remote service. The source for the client is shown below:The preferred way to set an end point address on the stub is to use thepackage hello; import javax.xml.rpc.Stub; import javax.naming.InitialContext; public class Client { public static void main(String[] args) throws Exception { | // get the initial context | InitialContext ctx = new InitialContext(); | | // lookup the service for Hello | HelloService svc = (HelloService) | ctx.lookup("xmlrpc:soap:hello.HelloService"); | | // get the hello stub | Hello hello = (Hello) svc.getHelloPort(); | | // set the end point address | ((Stub)hello)._setProperty("javax.xml.rpc.service.endpoint.address", | args.length > 0 ? args[0] :"http://localhost:9090/hello"); | | // invoke the service | System.out.println(hello.sayHello()); } }javax.xml.rpc.service.endpoint.address
property. Once you're done you can compile the client part of your Web Service:javac -d WEB-INF/classes Client.java5 Implementing the Server
The server implementation is much as if you were implementing any other Java interface. The server implementation class must extend the_Hello_Skeleton
class. In this case the server is very simple as shown below:Once you're done you can compile the server part of your Web Service:package hello; import java.rmi.Remote; import java.rmi.RemoteException; public class HelloImpl extends Hello_ServiceSkeleton { public String sayHello() throws RemoteException { | return "Hello World!"; } }javac -d WEB-INF/classes HelloImpl.java6 Deploying the Server
You can now create a WAR file and deploy the server in your favorite servlet container. Before creating the WAR you need to supply a standard web.xml file, which must be located in the WEB-INF directory. Please consult the one in the hello directory for an example. Then create the WAR as follows:If you're using Tomcat, you can copy thejar -cfM services.war WEB-INFservices.war
file into the Tomcatwebapps
directory and restart Tomcat. Then you're ready to run the client and test the Hello World application.As an alternative to using a servlet container, you can use the simple Web Server that ships with Novell exteNd WSSDK. You can start jwebserv like this:
For a full description of how to use the Novell exteNd WSSDK Server, please look here.jwebserv -verbose services.war7 Running the Client
Running the client is now straightforward. If you're using jwebserv you can run the client without any arguments, as http://localhost:9090/hello is the default binding. Below is the command line to run against Tomcat:The client program will print "Hello World!".java hello.Client http://localhost:8080/services/helloYou can now use the tunnel tool to inspect what goes over the wire. Run the tunnel on port 9999 like this:
In the above command line 9999 is the tunnel port and 9090 is the port where you Web Service is running (note the default is 8080 for Tomcat). After running this command you should see a window with two panels.tcptunnel 9999 localhost 9090You now need to run the client again through the tunnel:
What goes over the HTTP connection to the servlet container is the following SOAP message:java hello.Client http://localhost:9999/hello
<Envelope
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsd='http://www.w3.org/1999/XMLSchema'
xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'>
<Body>
<ns1:sayHello SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:ns1='http://www.hello'>
</ns1:sayHello>
</Body>
</Envelope>Figure 1: The SOAP message going from client to server in Hello World. And below is the SOAP response message coming back from the server:
<Envelope
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsd='http://www.w3.org/1999/XMLSchema'
xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'>
<Body>
<ns1:sayHelloResponse SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:ns1='http://www.hello'>
<result xsi:type='xsd:string'>Hello World!</result>
</ns1:sayHelloResponse>
</Body>
</Envelope>Figure 2: The SOAP message going from server back to client in Hello World.
Copyright © 2000-2003, Novell, Inc. All rights reserved. |