![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Utility Tools
CHAPTER 9
This chapter walks you through the basic steps and a typical scenario for using the Web Service Wizard to generate a Web Service consumer (a program that accesses a Web Service). Topics include:
To learn about the steps and scenarios for using the wizard when you want to create a Web Service, see Generating Web Services.
You can use the Web Service Wizard of the Novell exteNd Director development environment to generate the code needed for a Java-based consumer program to access any standard (SOAP-based) Web Service. The generated code handles all HTTP SOAP processing under the covers, enabling the consumer program to call the Web Service as a Java remote object (using RMI) and invoke its methods.
For input, the wizard requires a WSDL file that describes the Web Service to access. It can handle a wide variety of Web Service implementations, including:
The wizard generates Java source files based on JAX-RPC (Java API for XML-based RPC) and the Novell exteNd Web Services SDK (the JAX-RPC implementation included with Novell exteNd). JAX-RPC is the J2EE specification that provides Web Service support.
You can use the generated files as is or modify them when necessary. The advantage of this Java-oriented approach is that you can deal with Web Services using the familiar technologies of RMI and J2EE instead of coding lower-level SOAP APIs.
For an introduction to Web Service concepts, standards, and technologies, see Web Service Basics.
For detailed documentation on the wizard, see Web Service Wizard.
The process of developing your consumer program involves:
Preparing to generate by setting up your project
Providing a WSDL file that describes the Web Service for which you want the wizard to generate consumer code
Generating the consumer files by using the wizard
Examining the generated files that the wizard creates, including Java source for:
Editing the generated files to adjust the method calls to make and the Web Service location to point to
Using the generated files either as is or by including the consumer code in some other Java application
Running the consumer program in your development environment (for testing) and in the production environment
To prepare for using the Web Service Wizard, you:
Set up an appropriate project in the exteNd Director development environment.
The type of project you should create depends on how you ultimately plan to use the consumer code that the wizard will generate. For instance:
Add the archives required by the Web Services SDK to your project:
wssdk.jar, which contains the Web Services SDK API classes needed at runtime
agrootca.jar (when using SSL and the Novell exteNd trusted root certificates)
jakarta-regexp-1.2.jar (when using a pre-1.4 JDK and XML Schema with patterns)
mail.jar (when using attachments and javax.mail.internet.MimeMultipart)
Phaos_Crypto_FIPS.jar, Phaos_Security_Engine.jar, and Phaos_SSLava.jar (when using SSL; note that these JARs are already on the classpath of the exteNd Application Server)
You'll find these JARs in the Novell exteNd tools\compilelib directory.
Edit the classpath of your project so you can compile your consumer classes once they're generated and edited. You'll need to include:
wssdk.jar and the supporting JARs listed in Step 2 (as appropriate)
For J2EE projects, you'll also need j2ee_api_1_n.jar (it's included automatically when you create a J2EE project in the exteNd Director development environment).
To generate consumer code, you'll need to provide the Web Service Wizard with a WSDL file that describes the target Web Service. It's a good idea to obtain the file location or URL of this WSDL file before you start the wizard.
These are common scenarios:
For a Web Service developed in your organization, you might have the WSDL file on your file system or even in your project.
For an external Web Service, you should be able to get the WSDL file's URL from the appropriate Web site or registry.
Suppose you want to generate consumer code to use the Autoloan .NET Web Service, which is listed on the XMethods public registry under the name Equated Monthly Instalment (EMI) Calculator. That Web Service calculates and returns the monthly loan payment for a given term (number of months), interest rate, and loan amount.
In this case, you can go to the Web site www.xmethods.net to discover the URL for the corresponding WSDL file:
http://upload.eraserver.net/circle24/autoloan.asmx?wsdl
When you provide this URL to the Web Service Wizard, it will read the WSDL file to learn what it needs to know about the Autoloan Web Service:
<?xml version="1.0" encoding="utf-8"?> <definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s0="http://circle24.com/webservices/" targetNamespace="http://circle24.com/webservices/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <s:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://circle24.com/webservices/"> <s:element name="Calculate"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="Months" type="s:double" /> <s:element minOccurs="1" maxOccurs="1" name="RateOfInterest" type="s:double" /> <s:element minOccurs="1" maxOccurs="1" name="Amount" type="s:double" /> </s:sequence> </s:complexType> </s:element> <s:element name="CalculateResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="CalculateResult" nillable="true" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="string" nillable="true" type="s:string" /> </s:schema> </types> <message name="CalculateSoapIn"> <part name="parameters" element="s0:Calculate" /> </message> <message name="CalculateSoapOut"> <part name="parameters" element="s0:CalculateResponse" /> </message> <message name="CalculateHttpGetIn"> <part name="Months" type="s:string" /> <part name="RateOfInterest" type="s:string" /> <part name="Amount" type="s:string" /> </message> <message name="CalculateHttpGetOut"> <part name="Body" element="s0:string" /> </message> <message name="CalculateHttpPostIn"> <part name="Months" type="s:string" /> <part name="RateOfInterest" type="s:string" /> <part name="Amount" type="s:string" /> </message> <message name="CalculateHttpPostOut"> <part name="Body" element="s0:string" /> </message> <portType name="AutoloanSoap"> <operation name="Calculate"> <input message="s0:CalculateSoapIn" /> <output message="s0:CalculateSoapOut" /> </operation> </portType> <portType name="AutoloanHttpGet"> <operation name="Calculate"> <input message="s0:CalculateHttpGetIn" /> <output message="s0:CalculateHttpGetOut" /> </operation> </portType> <portType name="AutoloanHttpPost"> <operation name="Calculate"> <input message="s0:CalculateHttpPostIn" /> <output message="s0:CalculateHttpPostOut" /> </operation> </portType> <binding name="AutoloanSoap" type="s0:AutoloanSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="Calculate"> <soap:operation soapAction="http://circle24.com/webservices/Calculate" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <binding name="AutoloanHttpGet" type="s0:AutoloanHttpGet"> <http:binding verb="GET" /> <operation name="Calculate"> <http:operation location="/Calculate" /> <input> <http:urlEncoded /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding> <binding name="AutoloanHttpPost" type="s0:AutoloanHttpPost"> <http:binding verb="POST" /> <operation name="Calculate"> <http:operation location="/Calculate" /> <input> <mime:content type="application/x-www-form-urlencoded" /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding> <service name="Autoloan"> <documentation>This Web Service mimics a Simple Autoloan calculator.</documentation> <port name="AutoloanSoap" binding="s0:AutoloanSoap"> <soap:address location="http://upload.eraserver.net/circle24/autoloan.asmx" /> </port> <port name="AutoloanHttpGet" binding="s0:AutoloanHttpGet"> <http:address location="http://upload.eraserver.net/circle24/autoloan.asmx" /> </port> <port name="AutoloanHttpPost" binding="s0:AutoloanHttpPost"> <http:address location="http://upload.eraserver.net/circle24/autoloan.asmx" /> </port> </service> </definitions>
In the Autoloan WSDL, you can ignore the definitions for HttpGet and HttpPost (including message, portType, binding, and service port). Only the Soap definitions apply to the Web Service consumer program you're developing.
Notice that this Web Service exposes one method named calculate(). It takes a Calculate object containing three doubles (Months, RateOfInterest, and Amount) and returns a CalculateResponse object containing one string (CalculateResult). The Web Service Wizard will generate a corresponding remote interface in Java to support calling this method.
The types section specifies the XML Schema definitions for Calculate and CalculateResponse. The Web Service Wizard will generate corresponding type classes in Java to represent these objects.
There's a twist in how those Calculate and CalculateResponse classes will be used in the generated Autoloan consumer code. The Autoloan WSDL happens to follow the wrapper pattern defined by JAX-RPC, which dictates that method parameters in the remote interface should use basic types directly rather than the objects that wrap them. As a result, the calculate() method will be generated to take the three doubles (instead of Calculate) and return the string (instead of CalculateResponse). The wrapping and unwrapping of Calculate and CalculateResponse will be handled under the covers by the generated Autoloan stub class.
If you look in the binding section for AutoloanSoap, you'll see that this Web Service is defined as document style (as opposed to RPC style). That's typical of .NET Web Services. Binding style describes the format of SOAP messages and can affect interoperability with other Web Service environments:
The Web Service Wizard will generate the Java code needed to handle the specified binding style.
The port definition for AutoloanSoap (at the end of the WSDL file) specifies the address (URL) where the Web Service can be accessed:
http://upload.eraserver.net/circle24/autoloan.asmx
The Web Service Wizard will use this URL in the service and stub classes it generates for calling the Web Service.
Once you've set up your project and located the appropriate WSDL file, you're ready to use the Web Service Wizard. The wizard produces one Web Service consumer at a time, so you'll need to use it multiple times if you have several to develop.
Each time you launch the wizard, it uses the WSDL file and other input you provide to generate a set of consumer source files. Here's a summary of the process:
Select File>New>File to display the New File dialog and go to the Web Services tab.
Launch the Web Service Wizard by selecting Existing Web Service.
When the wizard prompts you for project location information, specify:
For example, suppose you're generating a consumer for the Autoloan Web Service. You might specify WebServiceConsumerSample as the target JAR project and com.exsamp.net as the package for generated classes:
When the wizard prompts you, specify the WSDL file that describes your target Web Service.
For example, when generating a consumer for the Autoloan Web Service, you specify the WSDL file URL obtained from the XMethods public registry:
When the wizard prompts you for Web Service type mappings, specify how data types defined in the WSDL (via XML Schema) are to be represented in the generated Java code.
The default is to create specific Java types for all of the complex XML types in the WSDL. That's usually appropriate and it's the right choice here for the Autoloan Web Service example:
When the wizard prompts you for class-generation and SOAP options, you must specify details about the code to create:
To get the files needed for a Web Service consumer, check Generate stubs (and leave Generate skeletons unchecked).
If necessary, you can override the default Service address (obtained from the WSDL) by specifying a different URL for the Web Service.
For example, these options will generate the appropriate consumer source files for the Autoloan Web Service:
NOTE: Support for jBroker Web 1.x applications is available via a backward-compatibility option. For more information, see If you choose jBroker Web 1.x compatibility (in the preceding chapter).
Click Finish when you're done specifying options for the Web Service consumer.
Once you finish the wizard, it generates everything you've specified for your Web Service consumer and updates other parts of your project with supporting changes:
When generating file names, the Web Service Wizard follows the naming rules specified by JAX-RPC. For a Web Service consumer, the resulting file names are based on the definitions in the WSDL.
For simplicity, this documentation uses xxx to represent the portion of a generated Web Service consumer file name that's derived from a WSDL definition.
Under the covers, the Web Service Wizard uses the Web Services SDK compilers when generating the Web Service consumer files listed above. In some cases, these compilers may generate additional code or files to support requirements specific to your application, such as:
For more information, see the Web Services SDK help.
The consumer code that the Web Service Wizard generates for the Autoloan Web Service consists of these standard files for Web Service access:
AutoloanSoap.java is the remote interface used by the stub class to support method calls for the Autoloan Web Service.
Autoloan.java is the service interface that's used in JAX-RPC to help clients obtain the stub for the Web Service.
AutoloanImpl.java is the service implementation class that handles instantiation of the stub (AutoloanSoap_Stub).
AutoloanSoap_Stub.java is the stub class. It passes method calls to the Autoloan Web Service as HTTP SOAP requests.
AutoloanSoapClient.java is a simple client application that obtains the stub (via the Service object) and then uses it to call the calculate() method of the Autoloan Web Service. (Note that this method call is generated as a comment. You'll learn what to do with it a little later, in Editing the generated files.)
And these application-specific files for mapping the complex types defined in the WSDL:
Calculate.java is a class that represents the complex type Calculate that's defined in the WSDL.
CalculateMarshaler.java is a class that handles serialization and deserialization for Calculate.
CalculateHolder.java is the Holder class required by JAX-RPC to implement type mapping support for Calculate. Note that this class is generated in the holders subdirectory.
CalculateResponse.java is a class that represents the complex type CalculateResponse that's defined in the WSDL.
CalculateResponseMarshaler.java is a class that handles serialization and deserialization for CalculateResponse.
CalculateResponseHolder.java is the Holder class required by JAX-RPC to implement type mapping support for CalculateResponse. Note that this class is generated in the holders subdirectory.
autoloan.asmx.xmlrpc.type.mappings specifies settings that tell the Web Services SDK how to configure the type mappings for Calculate and CalculateResponse. These mappings apply when data is converted from XML to Java or vice versa.
Since the generated stub and service classes automatically configure the mappings, this mappings file is not typically needed. It is provided for special situations (such as when you want to override a mapping).
The mappings file is generated in the base directory of the source tree (src).
When creating these files, the wizard adds them to your project on the directory path you've specified:
Follow these guidelines when editing the files generated by the Web Service Wizard:
Guideline |
Details |
---|---|
File you must edit |
|
Files you should not edit |
It's OK to edit any of the other generated files, but not typically required.
Before using the generated xxxClient.java file, you:
Must edit the process() method to call one or more methods of the target Web Service
May need to edit the getRemote() method to specify the correct location (binding) for accessing the target Web Service
The process() method is where the generated client application calls methods of the Web Service. Here you'll find commented code for calling each method defined in the generated remote interface and displaying return values on the console. For example:
public void process(String[] args) throws Exception
{
AutoloanSoap remote = getRemote(args);
// The following code has been generated for your testing convenience. In
// order to successfully test your Web Service, you must uncomment one or
// more of these lines and supply meaningful arguments where necessary.
// Once you have modified the test method(s) below, compile this class and
// execute it from a command line with your class path set appropriately.
// System.out.println("Test Result = " + remote.calculate(double, double, double));
}
You need to modify this code as follows:
Provide appropriate arguments for each method call, either as hardcoded values or as parameters to be furnished at runtime. For runtime arguments, you may also want to add code that validates the values supplied.
Check the return data type to make sure it can be converted using toString(). If not, use an alternative to System.out.println for displaying the data returned.
Here's what the line with the calculate() method call looks like after editing:
System.out.println("Autoloan Web Service\n " +
"Loan input data:\n 24 months, 8%, $15000\n " +
"Output from the Web Service:\n " +
remote.calculate(24, 8, 15000));
This section explains the basic use of the getRemote() method and how to modify it when you need to specify binding information.
Basic use The getRemote() method is where the generated client application obtains the remote object to handle its method calls to the Web Service. That remote object is an instance of the generated stub class (xxx_Stub). To create the stub instance, getRemote() does the following:
Instantiates the Service object (from the service interface and implementation classes, xxxService and xxxServiceImpl) via JNDI lookup
Calls a method that the Service object provides (in the service interface) to get the stub
Here's an example of the typical code generated for getRemote(). Normally, you don't need to edit it:
public AutoloanSoap getRemote(String[] args) throws Exception { InitialContext ctx = new InitialContext(); String lookup = "xmlrpc:soap:com.exsamp.net.Autoloan"; Autoloan service = (Autoloan)ctx.lookup(lookup); AutoloanSoap remote = (AutoloanSoap)service.getAutoloanSoap(); return remote; }
Specifying binding information The wizard includes the binding information for your target Web Service in the generated stub class (xxx_Stub.java) and service implementation class (xxxServiceImpl.java). The binding provides the service endpoint address where the Web Service can be accessed. In a WSDL file, this address is the URL in the soap:address location element.
As an alternative, you can specify the binding to use when creating the stub instance in the getRemote() method. This enables you to override the binding in the stub class (such as when the Web Service has moved to a new location). You just need to add a line of code to set the address property for the stub:
public AutoloanSoap getRemote(String[] args) throws Exception { InitialContext ctx = new InitialContext(); String lookup = "xmlrpc:soap:com.exsamp.net.Autoloan"; Autoloan service = (Autoloan)ctx.lookup(lookup); AutoloanSoap remote = (AutoloanSoap)service.getAutoloanSoap(); ((javax.xml.rpc.Stub)remote)._setProperty("javax.xml.rpc.service.endpoint.address", "http://upload.eraserver.net/circle24/autoloan.asmx"); return remote; }
How you use the Web Service consumer code that you have at this point depends on the nature of the application you're developing. Sometimes you might want to enhance the generated xxxClient.java file and include it in your application. At other times you may just copy syntax from xxxClient.java into your own classes. But in either case, you'll always need the generated remote interface, service, and stub files.
Before you start any application-specific coding, it's a good idea to test the basic xxxClient to make sure your consumer code works as expected. You'll first need to build your project to compile the source files. Then you can run xxxClient, as described in the next section.
The generated Web Service consumer program xxxClient is a standard Java application. You can run it in either of these ways:
To help you test your generated client quickly and easily, the exteNd Director development environment provides the Web Service Wizard Client Runner. This facility lists the client applications in your current project and lets you select one to execute. For each run, it automatically sets the classpath to include all required files and lets you supply command-line arguments.
Open the project that contains the compiled client class you want to run.
Select Tools>Run Web Service Client Class to display the Client Runner window.
Select a client from the Client class to run dropdown.
This dropdown lists every compiled class in your project that has a main() method.
Type any command-line Arguments required by your client (use a space to separate each argument).
Click Run to execute your client and see its output in the display console portion of the window.
For example, here's what it looks like to execute the generated AutoloanSoapClient class using the Client Runner:
When AutoloanSoapClient runs, it calls the calculate() method of the Autoloan Web Service and passes a Calculate object containing loan data (term, rate, amount). The calculate() method returns a CalculateResponse object containing a string of payment information, which AutoloanSoapClient displays on the screen:
Running com.exsamp.net.AutoloanSoapClient...
*********************
Autoloan Web Service
Loan input data:
24 months, 8%, $15000
Output from the Web Service:
Equated Monthly Instalment (EMI) For the Amount $15000 is $678
*********************
You can also execute the generated client from the command prompt of your operating system. Doing so demands that you set the classpath to include all required files (such as the generated consumer classes, wssdk.jar, and so on).
The recommended approach is to use the Web Service Wizard Client Runner to display and copy the command line for your client (as described in the preceding section). Then you can paste that line to your command prompt and run it.
If you plan to run the client on other computers (beyond your development machine), make sure they have access to all of the files listed in this command line.
Copyright © 2004 Novell, Inc. All rights reserved. Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved. more ...