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:
- Write the WSDL for the service.
- Compile WSDL and create stubs and skeletons using the wsdl2soap compiler.
- Implement the client.
- Implement the server.
- Deploy the server in some servlet container.
- 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.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:<?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>rmi2wsdl -xsd http://www.w3.org/2001/XMLSchema -soap http://localhost:9090/helloWSDL helloWSDL.HelloThe 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 calledWEB-INF/classes
, since this directory structure is necessary when creating the servlet WAR file later. To create this directory execute the following commands:Also, ensure that the Novell exteNd WSSDK binaries are in your PATH. For example:mkdir WEB-INF
cd WEB-INF
mkdir classesFinally, 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 wsdl2java compiler on the Hello.wsdl file to compile the WSDL document and generate the SOAP bindings from the above WSDL file:set CLASSPATH=%CLASSPATH%;C:\jakarta-tomcat-3.2.1\lib\servlet.jarThe 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 thewsdl2java -package helloWSDL -d WEB-INF/classes Hello.wsdlhelloWSDL
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 theCLASSPATH
. Set yourCLASSPATH
as follows (depending on operating system and shell):The client implementation uses JNDI to lookup a stub for the remote service. The source for the client is shown below:set CLASSPATH=WEB-INF/classes:$CLASSPATHOnce you're done you can compile the client part of your Web Service: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()); } }javac -d WEB-INF/classes Client.java4 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:Once you're done you can compile the server part of your Web Service:package helloWSDL; 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.java5 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 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".jar -cfM services.war WEB-INFAs 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: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.java helloWSDL.Client
Copyright © 2000-2003, Novell, Inc. All rights reserved. |