|
Home
TOC Index |
|
A Simple Example: HelloWorld
This example shows you how to use JAX-RPC to create a Web service named
HelloWorld. A remote client of theHelloWorldservice can invoke thesayHellomethod, which accepts a string parameter and then returns a string.HelloWorld at Runtime
Figure 9-1 shows a simplified view of the
HelloWorldservice after it's been deployed. Here's a more detailed description of what happens at runtime:
- To call a remote procedure, the
HelloClientprogram invokes a method on a stub, a local object that represents the remote service.- The stub invokes routines in the JAX-RPC runtime system.
- The runtime system converts the remote method call into a SOAP message and then transmits the message as an HTTP request.
- When the server receives the HTTP request, the JAX-RPC runtime system extracts the SOAP message from the request and translates it into a method call.
- The JAX-RPC runtime system invokes the method on the tie object.
- The tie object invokes the method on the implementation of the
HelloWorldservice.- The runtime system on the server converts the method's response into a SOAP message and then transmits the message back to the client as an HTTP response.
- On the client, the JAX-RPC runtime system extracts the SOAP message from the HTTP response and then translates it into a method response for the
HelloClientprogram.Figure 9-1 The
HelloWorldExample at RuntimeThe application developer only provides the top layers in the stacks depicted by Figure 9-1. Table 9-1 shows where the layers originate.
HelloWorld Files
To create a service with JAX-RPC, an application developer needs to provide a few files. For the
HelloWorldexample, these files are in the<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hellodirectory:
HelloIF.java- the service definition interfaceHelloImpl.java- the service definition implementation class, it implements theHelloIFinterfaceHelloClient.java- the remote client that contacts the service and then invokes thesayHellomethodconfig.xml- a configuration file read by thewscompiletooljaxrpc-ri.xml- a configuration file read by thewsdeploytoolweb.xml- a deployment descriptor for the Web component (a servlet) that dispatches to the serviceSetting Up
If you haven't already done so, follow these instructions in the chapter Getting Started With Tomcat:
Building and Deploying the Service
The basic steps for developing a JAX-RPC Web service are as follows.
- Code the service definition interface and implementation class.
- Compile the service definition code of step 1.
- Package the code in a WAR file.
- Generate the ties and the WSDL file.
- Deploy the service.
The sections that follow describe each of these steps in more detail.
Coding the Service Definition Interface and Implementation Class
A service definition interface declares the methods that a remote client may invoke on the service. The interface must conform to a few rules:
- It extends the
java.rmi.Remoteinterface.- It must not have constant declarations, such as
public final static.- The methods must throw the
java.rmi.RemoteExceptionor one of its subclasses. (The methods may also throw service-specific exceptions.)- Method parameters and return types must be supported JAX-RPC types. See the section Types Supported By JAX-RPC.
In this example, the service definition interface is
HelloIF.java:package hello; import java.rmi.Remote; import java.rmi.RemoteException; public interface HelloIFextends Remote{ public String sayHello(String s)throws RemoteException; }In addition to the interface, you'll need to code the class that implements the interface. In this example, the implementation class is called
HelloImpl:package hello; public class HelloImplimplements HelloIF{ public String message ="Hello"; public String sayHello(String s) { return message + s; } }Compiling the Service Definition Code
To compile
HelloIF.javaandHelloImpl.java, go to the<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hellodirectory and type the following:ant compile-serverThis command places the resulting class files in the
build/sharedsubdirectory.Packaging the WAR File
To create the WAR file that contains the service code, type these commands:
ant setup-web-inf ant packageThe
setup-web-inftarget copies the class and XML files to thebuild/WEB-INF subdirectory. Thepackagetarget runs thejarcommand and bundles the files into a WAR file nameddist/hello-portable.war. This WAR file is not ready for deployment because it does not contain the tie classes. You'll learn how to create a deployable WAR file in the next section. Thehello-portable.warcontains the following files:WEB-INF/classes/hello/HelloIF.class WEB-INF/classes/hello/HelloImpl.class WEB-INF/jaxrpc-ri.xml WEB-INF/web.xmlThe class files were created by the
compile-servertarget shown in the previous section. Theweb.xmlfile is the deployment descriptor for the Web application that implements the service. Unlike theweb.xmlfile, thejaxrpc-ri.xmlfile is not part of the specifications and is implementation-specific. Thejaxrpc-ri.xmlfile for this example follows:<?xml version="1.0" encoding="UTF-8"?> <webServices xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/dd" version="1.0" targetNamespaceBase="http://com.test/wsdl" typeNamespaceBase="http://com.test/types" urlPatternBase="/ws"> <endpoint name="MyHello" displayName="HelloWorld Service" description="A simple web service" interface="hello.HelloIF" implementation="hello.HelloImpl"/> <endpointMapping endpointName="MyHello" urlPattern="/hello"/> </webServices>Several of the
webServicesattributes, such astargetNamespaceBase, are used in the WSDL file, which you'll create in the next section. (WSDL files can be complex and are not discussed in this tutorial. See Further Information.) Note that theurlPatternvalue (/hello) is part of the service's URL, which is described in the section Verifying the Deployment).For more information about the syntax of the
jaxrpc-ri.xmlfile, see the XML Schema file:<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/common/jax-rpc-ri-dd.xsd.Generating the Ties and the WSDL File
To generate the ties and the WSDL file, type the following:
ant process-warThis command runs the
wsdeploytool as follows:wsdeploy -tmpdir build/wsdeploy-generated -o dist/hello-deployable.war dist/hello-portable.warThis command runs the
wsdeploytool, which performs these tasks:
- Reads the
dist/hello-portable.warfile as input- Gets information from the
jaxrpc-ri.xmlfile that's inside thehello-portable.warfile- Generates the tie classes for the service
- Generates a WSDL file named
MyHello.wsdl- Packages the tie classes, the
Hello.wsdlfile, and the contents ofhello-portable.warfile into a deployable WAR file nameddist/hello-jaxrpc.warThe -
tmpdiroption specifies the directory wherewsdeploystores the files that it generates, including the WSDL file, tie classes, and intermediate source code files. If you specify the -keepoption, these files are not deleted.There are several ways to access the WSDL file generated by
wsdeploy:
- Run
wsdeploywith the -keepoption and locate the WSDL file in the directory specified by the -tmpdiroption.- Unpack (
jar-x) the WAR file output bywsdeployand locate the WSDL file in theWEB-INFdirectory.- Deploy and verify the service as described in the following sections. A link to the WSDL file is on the HTML page of the URL shown in Verifying the Deployment.
Note that the
wsdeploytool does not deploy the service; instead, it creates a WAR file that is ready for deployment. In the next section, you will deploy the service in thehello-jaxrpc.warfile that was created bywsdeploy.Deploying the Service
To deploy the service, type the following:
ant deployFor subsequent deployments , run
antredeployas described in the section Iterative Development.Verifying the Deployment
To verify that the service has been successfully deployed, open a browser window and specify the service endpoint's URL:
http://localhost:8080/hello-jaxrpc/helloThe browser should display a page titled Web Services, which lists the port name
MyHellowith a status ofACTIVE. This page also has a URL to the service's WSDL file.The
hello-jaxrpcportion of the URL is the context path of the servlet that implements theHelloWorldservice. This portion corresponds to the prefix of thehello-jaxrpc.warfile. The/hellostring of the URL matches the value of theurlPatternattribute of thejaxrpc-ri.xmlfile. Note that the forward slash in the/hellovalue ofurlPatternis required. For a full listing of thejaxrpc-ri.xmlfile, see Packaging the WAR File.Undeploying the Service
At this point in the tutorial, do not undeploy the service. When you are finished with this example, you can undeploy the service by typing this command:
ant undeployBuilding and Running the Client
To develop a JAX-RPC client, you follow these steps:
- Generate the stubs.
- Code the client.
- Compile the client code.
- Package the client classes into a JAR file.
- Run the client.
The following sections describe each of these steps.
Generating the Stubs
Before generating the stubs, be sure to install the
Hello.wsdlfile according to the instructions in Deploying the Service. To create the stubs, go to the<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hellodirectory and type the following:ant generate-stubsThis command runs the
wscompiletool as follows:wscompile -gen:client -d build/client -classpath build/shared config.xmlThe
-gen:clientoption instructswscompileto generate client-side classes such as stubs. The-doption specifies the destination directory of the generated files.The
wscompiletool generates files based on the information it reads from theHello.wsdlandconfig.xmlfiles. TheHello.wsdlfile was intalled on Tomcat when the service was deployed. The location ofHello.wsdlis specified by the <wsdl> element of theconfig.xmlfile, which follows:<?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="hello"/> </configuration>The tasks performed by the
wscompiletool depend on the contents of theconfig.xmlfile. For more information about the syntax of theconfig.xmlfile, see the XML Schema file:<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/common/jax-rpc-ri-config.xsd.Coding the Client
HelloClientis a stand-alone program that calls thesayHellomethod of theHelloWorldservice. It makes this call through a stub, a local object which acts as a proxy for the remote service. Because the stubs is created before runtime (bywscompile), it is usually called a static stub.To create the stub,
HelloClientinvokes a private method namedcreateProxy. Note that the code in this method is implementation-specific and might not be portable because it relies on theMyHello_Implobject. (TheMyHello_Implclass was generated bywscompilein the preceding section.) After it creates the stub, the client program casts the stub to the typeHelloIF, the service definition interface.The source code for
HelloClientfollows:package hello; import javax.xml.rpc.Stub; public class HelloClient { public static void main(String[] args) { try {Stub stub = createProxy(); HelloIF hello = (HelloIF)stub; System.out.println(hello.sayHello("Duke!"));} catch (Exception ex) { ex.printStackTrace(); } } private static Stub createProxy() { // Note: MyHello_Impl is implementation-specific. return (Stub)(new MyHello_Impl().getHelloIFPort()); } }Compiling the Client Code
Because the client code refers to the stub classes, be sure to follow the instructions in Generating the Stubs before compiling the client. To compile the client, go to the
<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hellodirectory and type the following:ant compile-clientPackaging the Client
To package the client into a JAR file, type the following command:
ant jar-clientThis command creates the
dist/hello-client.jarfile.Running the Client
To run the
HelloClientprogram, type the following:ant runThe program should display this line:
Hello Duke!The
ant runtarget executes this command:java -classpath <cpath>hello.HelloClientThe classpath includes the
hello-client.jarfile 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.Iterative Development
In order to show you each step of development, the previous sections instructed you to type several
antcommands. However, it would be inconvenient to type all of those commands during iterative development. To save time, after you've initially deployed the service, you can iterate through these steps:
- Test the application.
- Edit the source files.
- Execute
antbuildto create the deployable WAR file.- Execute
antredeployto undeploy and deploy the service.- Execute
antbuild-staticto create the JAR file for a client with static stubs.- Execute
antrun.Implementation-Specific Features
To implement the JAX-RPC Specification, the Java WSDP requires some features that are not described in the specification. These features are specific to the Java WSDP and might not be compatible with implementations from other vendors. For JAX-RPC, the implementation-specific features of the Java WSDP follow:
config.xml- See Generating the Stubs for an example.jaxrpc-ri.xml- See Packaging the WAR File for an example.- ties - In the preceding example, the ties are in the
hello-jaxrpc.warfile, which is implementation-specific. (Thehello-portable.warfile, however, is not implementation-specific.)- stubs - The stubs are in the
hello-client.jarfile. Note that theHelloClientprogram instantiatesMyHelloImpl, a static stub class that is implementation-specific. Because they do not contain static stubs, dynamic clients do not have this limitation. For more information about dynamic clients, see the sections A Dynamic Proxy Client Example and A Dynamic Invocation Interface (DII) Client Example .- tools - The
wsdeploy,wscompile, anddeploytoolutilities.- support for collections - See Table 9-1.
|
Home
TOC Index |
|
This tutorial contains information on the 1.0 version of the Java Web Services Developer Pack.
All of the material in The Java Web Services Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.