|
There is only one parameter for the executeTrade( ) method, an Object[] called params. The
objects in this array must be cast to their corresponding types: a String, an Integer, and a
Boolean. I like to put class casts inside a try/catch block in case the caller makes a mistake. That
way I can do something useful if the method is called incorrectly, even if
that means simply returning a description of the error. In Chapter 7, we'll
look at generating SOAP faults for situations like this. The information
passed in the array is used to generate a string that describes the
parameters, and that string is stored in the result
variable that is returned to the caller.
Now we can modify the client application so that it passes an
appropriate Object[]as the parameter to the executeTrade service method. The multiParams variable is declared as an Object[], and is populated with the String MINDSTRM, an Integer with the value of 100, and a Boolean with the value of true. Since we're using an array of Java Object instances, we don't use Java primitives as
elements of the array. Instead we wrap those primitive values in their Java
object equivalents. The second parameter of the Parameter constructor is Object[].class, which is the class for an array of object
instances. package javasoap.book.ch5;
import java.net.*;
import java.util.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
public class TradingClient {
public static void main(String[] args)
throws Exception {
URL url =
new URL(
"http://georgetown:8080/soap/servlet/rpcrouter");
Call call = new Call( );
call.setTargetObjectURI("urn:BasicTradingService");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
Object[] multiParams = { "MINDSTRM", new Integer(100),
new Boolean(true) };
Vector params = new Vector( );
params.addElement(new Parameter("params",
Object[].class, multiParams, null));
call.setParams(params);
try {
call.setMethodName("executeTrade");
Response resp = call.invoke(url, "");
Parameter ret = resp.getReturnValue( );
Object value = ret.getValue( );
System.out.println("Trade Description: " + value);
}
catch (SOAPException e) {
System.err.println("Caught SOAPException (" +
e.getFaultCode( ) + "): " +
e.getMessage( ));
}
}
}
If all goes well, the result of executing the executeTrade( ) service method is: Trade Description: Buy 100 of MINDSTRM
We could force the service object down another path by changing
the order of the parameters in the multiParams
array. In this case, we would encounter a class cast exception, and the method
would return an error string.
Here is the SOAP envelope for the proper invocation of the executeTrade( ) service method: <SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<ns1:executeTrade xmlns:ns1="urn:BasicTradingService"
SOAP-ENV:encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/">
<params
xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:Array" ns2:arrayType="xsd:anyType[3]">
<item xsi:type="xsd:string">MINDSTRM</item>
<item xsi:type="xsd:int">100</item>
<item xsi:type="xsd:boolean">true</item>
</params>
</ns1:executeTrade>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The params
element is typed by assigning the xsi:type
attribute the value of ns2:Array. The only
difference from the homogeneous case is that every array element has a
different value assigned to the ns2:arrayType
attribute. The value xsd:anyType[3] indicates that
the array contains 3 elements, each of which can be of any valid data type.
[2]
Now let's take a look at passing arrays as parameters using
GLUE. The BasicTradingService class can be deployed
in GLUE without modification. We'll use a simple Java application to get this
service started: package javasoap.book.ch5;
import electric.util.Context;
import electric.registry.Registry;
import electric.server.http.HTTP;
public class BasicTradingApp {
public static void main( String[] args )
throws Exception {
HTTP.startup("http://georgetown:8004/glue");
Context context = new Context( );
context.addProperty("activation", "application");
context.addProperty("namespace",
"urn:BasicTradingService");
Registry.publish("urn:BasicTradingService",
javasoap.book.ch5.BasicTradingService.class, context );
}
}
Compile and execute the application, and the service is
deployed. Now let's write a simple example to access the service using the
GLUE API. First let's look at the interface to the service, IBasicTradingService: package javasoap.book.ch5;
public interface IBasicTradingService {
int getTotalVolume(String[] symbols);
String executeTrade(Object[] params);
}
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|