Hello World Web Service

This is a simple example that will show you how to develop a Web Servic 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.

1 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, which 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.

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

3 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

4 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

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

6 GET Support

When you deploy the Web Service in a servlet container or Novell exteNd WSSDK Server, a default HTML page is provided when you hit the http url for the service in the browser. This page has 4 links on it. First one is WSDL document which shows you the WSDL implemented by the service. The second one is Remote interface which shows the java remote interface generated for WSDL. Thr third one is Type Mappings which shows you which xml types are mapped to which java classes. For more information on Type Mappings please click here. The fourth one is Test service which produces html forms at runtime to invoke operations defined in WSDL or in remote interface. It allows you to enter information for the operation parameters and once all the information is collected, it invokes the operation and shows the results. You have an option to disable this feature for security purposes. The jbroker.web.test.disable parameter in the deployment descriptor of the servlet should be set to false in order to diable Test service behavior.

The default GET behavior can be overridden by writing doGet method of the servlet in the implementation. Please note that implementing doGet will not override the default GET behavior if you deploy the service in Novell exteNd WSSDK Server.

7 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 © 2000-2003, Novell, Inc. All rights reserved.