Hello World Web Service

This is a simple example that will show you how to develop a Web Service client and service starting from a WSDL document. The flow of this example is very similar to the hello example with RMI because RMI and WSDL have same function as a contract between client and server. Again, the development process can be divided into the following steps:

  1. Write the WSDL for the service.

  2. Compile WSDL and create stubs and skeletons using the wsdl2soap compiler.

  3. Implement the client.

  4. Implement the server.

  5. Deploy the server in some servlet container.

  6. Run the client against the server.

You can use the supplied ANT script to build the example rather than issuing the commands manually. We show the steps in more detail here to fully describe what is required to build a Web Service using the Novell exteNd Web Services SDK.

Hello WSDL Document

Below is the WSDL for the Hello World Application. The portType Hello has one operation, sayHello which has no input messages but and output message that contains a string. As with RMI, the WSDL document serves as a contract between the object implementation and its clients.

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="HelloService"
 targetNamespace="http://www.hello"
 xmlns="http://schemas.xmlsoap.org/wsdl/"
 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:tns="http://www.hello"
 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <types/>
 <message name="sayHelloInput"/>
 <message name="sayHelloOutput">
  <part name="result" type="xsd:string"/>
 </message>
 <portType name="Hello">
  <operation name="sayHello">
   <input message="tns:sayHelloInput"/>
   <output message="tns:sayHelloOutput"/>
  </operation>
 </portType>
 <binding name="HelloBinding" type="tns:Hello">
  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="sayHello">
   <soap:operation soapAction="http://www.hello/sayHello"/>
   <input>
    <soap:body
     encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
     namespace="http://www.hello" use="encoded"/>
   </input>
   <output>
    <soap:body
     encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
     namespace="http://www.hello" use="encoded"/>
   </output>
  </operation>
 </binding>
 <service name="HelloService">
  <port binding="tns:HelloBinding" name="HelloPort">
   <soap:address location="http://localhost:9090/helloWSDL"/>
  </port>
 </service>
</definitions>

As described previously, WSDL documents are not normally written by hand, but often generated from some other interface description such as RMI. As an example, the above WSDL is generated from the Hello RMI using the following command:

   rmi2wsdl -xsd http://www.w3.org/2001/XMLSchema -soap http://localhost:9090/helloWSDL helloWSDL.Hello

The WSDL document supplied with this example has a SOAP binding where the service URL is "http://localhost:9090/helloWSDL". Depending on where you deploy the service, you may have to change this string accordingly.

Compile WSDL and Generating SOAP Bindings

We'll use a target directory called WEB-INF/classes, since this directory structure is necessary when creating the servlet WAR file later. To create this directory execute the following commands:

   mkdir WEB-INF
   cd WEB-INF
   mkdir classes

Also, ensure that the Novell exteNd WSSDK binaries are in your PATH. For example:

   set PATH=C:\wssdk\bin\win32;%PATH%

Finally, you must ensure that the Servlet library is in your CLASSPATH. If you're using Tomcat you might do:

   set CLASSPATH=%CLASSPATH%;C:\jakarta-tomcat-3.2.1\lib\servlet.jar

Run the wsdl2java compiler on the Hello.wsdl file to compile the WSDL document and generate the SOAP bindings from the above WSDL file:

   wsdl2java -package helloWSDL -d WEB-INF/classes Hello.wsdl

The wsdl2java compiler generates the Java code to the WEB-INF/classes directory, and compiles the generated Java code to the same directory. Since wsdl2java invokes rmi2soap under the covers, the usual classes are created in the helloWSDL Java package:

Hello.java // The generated RMI interface
Hello.class // compiled Hello file
HelloBinding_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 wsdl2java with the -keep flag if you wish to keep the source files for the stubs and skeletons. Please consult the wsdl2java man page for a detailed description of the command line flags.

Implementing the Client

Before compiling the client, you must have the classes directory available in the CLASSPATH. Set your CLASSPATH as follows (depending on operating system and shell):

   set CLASSPATH=WEB-INF/classes:$CLASSPATH

The client implementation uses JNDI to lookup a stub for the remote service. The source for the client is shown below:

package helloWSDL;
                                                                           
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:helloWSDL.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/helloWSDL");
    |                                                                      
    |   // invoke the service
    |   System.out.println(hello.sayHello());
    }
}
                                                                           

Once you're done you can compile the client part of your Web Service:

   javac -d WEB-INF/classes Client.java

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_ServiceSkeleton class. In this case the server is very simple as shown below:

package helloWSDL;
                                                                           
import java.rmi.Remote;
import java.rmi.RemoteException;
                                                                           
public class HelloImpl extends Hello_ServiceSkeleton
{
    public String sayHello() throws RemoteException
    {
    |   return "Hello World!";
    }
}

Once you're done you can compile the server part of your Web Service:

   javac -d WEB-INF/classes HelloImpl.java

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:

   jar -cfM services.war WEB-INF

If you're using Tomcat, you can copy the services.war file into the Tomcat webapps directory and restart Tomcat. Then you're ready to run the client and test the Hello World application. Note that if you use Tomcat the URL for this Web Service must be changed on the command line (or in the WSDL document) to "http://localhost:8080/services/helloWSDL".

As an alternative to using a servlet container, you can use the simple Web Server that ships with the Novell exteNd WSSDK. For a full description of how to use the Novell exteNd WSSDK Server, please look here. If you use the Novell exteNd WSSDK Server, you can deploy and run the client with no modifications.

Running the Client

Running the client is now straightforward:

   java helloWSDL.Client

The client program will print "Hello World!". Please refer to the RMI Hello World example to see the SOAP message going from client to server.



Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.