Last month in Part I (WSJ Vol. 2 Issue 1) we discussed J2ME and
accessing Web services from wireless devices using the XML-RPC
protocol. In this article, we will consider SOAP as a vehicle for
accessing Web services from wireless devices, comparing and
contrast-ing it with XML-RPC. Our sample application will again be a
J2ME midlet, however, we will use EnhydraME's kSOAP rather than
kXML-RPC to provide the protocol's implementation.
Overview of SOAP
The Simple Object Access Protocol is, according to the 1.1
specification, "a lightweight protocol for exchange of information in
a decentralized, distributed environment." The protocol is entirely
based on XML, vendor-neutral, and one of the cornerstone technologies
in the Web services revolution. It is quite similar to XML-RPC, but
we will examine that more closely in the next section.
SOAP was originally conceived and developed at Microsoft between 1998
and 1999. SOAP did not, however, gain widespread attention until
DevelopMentor, IBM, Lotus, and Microsoft submitted the SOAP 1.1
version to the W3C on April 26, 2000. With both IBM and Microsoft
behind it, the industry began to give SOAP some serious
consideration. As of this writing, the SOAP 1.2 specification is
being drafted by the W3C's XML Protocol Working Group. The latest
draft of the 1.2 spec can be found at www.w3.org/TR/soap12/.
When examining SOAP, it is important to identify the three main
components of any SOAP message: the SOAP envelope, rules for encoding
data, and a request/response interaction mechanism. The SOAP
messaging architecture can be compared to a postal system (see Figure
1). A document is enclosed in an envelope and that envelope is
transmitted via the transport mechanism, the mail system in our
analogy, or HTTP across a network in the case of SOAP. With the mail,
a zip code identifies the locale an envelope should be delivered to;
with SOAP, HTTP header data provides such routing information. At
this point, the analogy breaks down. Whereas the "last mile service"
provided by a postal carrier is directed by the street address on the
envelope, it is information encoded in the body of the XML document
itself that ultimately directs the SOAP request to the specific
service on the server.
XML-RPC vs SOAP
Although SOAP and XML-RPC have similar roots (XML-RPC is based on a
subset of the original SOAP spec that was developed at Microsoft in
the late 1990s), they are very different animals. Both XML-RPC and
SOAP are XML-based protocols for communication and data exchange, so
when should one be chosen over the other? We'll take a look at their
strengths and weaknesses, and then evaluate these two protocols from
a business perspective.
XML-RPC is an extremely lightweight mechanism for invoking XML-based
services. It is a clean, simple protocol that provides the minimum
overhead necessary to invoke remote services and exchange data in a
platform-, language-, and vendor-neutral manner. It defines six
simple data types and two complex types. The result is that XML-RPC
is a highly-efficient lightweight protocol. Messages are simple to
construct, simple to parse, simple to debug, and are easily
human-readable. XML-RPC requires a minimal amount of active memory
for processing, building, and parsing messages, and produces a thin
message body to be exchanged between client and server.
In contrast, SOAP is a fatter protocol (although generally considered
lightweight). In exchange for some additional overhead, SOAP provides
namespace awareness, a sophisticated data-typing mechanism, and a
flexible messaging paradigm. The W3C's XML Namespaces specification
is leveraged to provide namespace awareness, and the XML Schema
specification provides the data-typing mechanism. As such, SOAP
supports over 40 standard data types and provides the capabilities to
define custom simple and complex data types. This provides a
tremendous degree of flexibility in terms of describing robust data
structures with intricate relationships with other data contained in
the message body.
The SOAP architecture also introduces a flexible messaging
architecture, supporting a variety of messaging paradigms, including
unidirectional, bidirectional, multicast (publish-subscribe), and
sequentialmessaging (multiple parties chained together in a
particular order). One aspect that facilitates these paradigms is the
ability of a SOAP message to include a header section. This allows
security, transaction, and routing information to be exchanged
between multiple parties. For example, a client can send a SOAP
request with an intended destination, but also declare in the SOAP
envelope's headers that a particular party should receive the
message, process the pertinent header information, and then pass the
message on to the next party in the chain (or the intended recipient
if no other parties have been declared). One final distinction is
that SOAP supports asynchronous messaging, while XML-RPC requires a
synchronous communication between the two parties in an exchange.
With all of these differences between the two protocols, executives,
project managers, and wireless architects alike are wondering - "How
do I make a choice between SOAP and XML-RPC for a particular wireless
project or system?" Well, even if you weren't wondering that, we're
going to tell you anyway.
In a nutshell, XML-RPC provides a fast, compact protocol for
exchanging data and invoking services in a neutral, standardized way.
If application size, memory, and bandwidth are your top priorities,
then XML-RPC is the way to go. On the other hand, if your application
requires a robust data-typing mechanism, extensive security or
transaction support, or a flexible messaging architecture, then SOAP
is your answer. Also, SOAP is more mainstream than XML-RPC, so if
your application needs to access a variety of services that you have
no control over, SOAP may be a better match from an interoperability
perspective. To break it down into more detail, Table 1 that outlines
the business justifications for using each protocol.
Wireless SOAP Example
In our previous article we developed a sample application using
kXML-RPC (http://kxmlr pc.enhydra.org), an open-source implementation
of the XML-RPC protocol for micro devices maintained by Enhydra.
kSOAP (http://ksoap.enhydra.org) is another Enhydra Micro Edition
project, providing SOAP support for mobile devices. We will create a
MIDP interface with the kSOAP libraries underneath to activate a
SOAP-based Web service
located on a remote HTTP server.
For our application, we will be using three classes from the kSOAP
library to handle the marshalling and unmarshalling of data via SOAP:
- HttpTransport: A convenient API that enables SOAP calls via
HTTP using the J2ME Generic Connection Framework
- ClassMap: Provides namespace support and a two-way mapping
between namespace-qualified XML names and Java classes
- SoapObject: A generic object used to represent any SOAP
object within the body of a SOAP request or response. SOAP objects
can also be nested
Rather than creating both the client and the service we are
accessing, we will simply access an existing service. Xmet hods.com
provides a Web service registry for publicly available Web services.
We will be invoking a service provided by Cape Clear that gathers and
disseminates airport weather information on behalf of a client. The
details regarding that service can be located at:
www.xmethods.com/detail.html?id=129, and the source code for this
midlet (Airport Weather.java) can be downloaded from the kSOAP Web
site at http://ksoap.enhydra.org/software/downloads/index.html.
In creating our sample SOAP midlet (AirportWeather.java), the process
is identical to the one we used in Part 1. This time, the packages
and names have been changed to protect the innocent. We will import,
extend, and use classes from the kSOAP library rather than the
kXML-RPC library.
The first step, obviously, is to import the necessary packages and
declare the MIDP components that will be used in the application.
After this, we define the midlet's constructor, initializing all the
UI components, and add them to the display as necessary. With that
complete, we need to fill in the three other lifecycle methods. In
the startApp() method, we simply bring the MIDP display into action.
Since we don't use any shared resources, the pauseApp() method is
blank. Finally, the destroyApp() method releases the local resources
that we have allocated for our midlet.
As with Part 1, all the action takes place in the commandAction()
method. This method is called anytime the user performs a command
event (pressing a key, selecting an item from a list, etc.). The
Command and Displayable objects are then queried to determine which
component has actually been activated/ deactivated, and the
appropriate actions are performed. When our midlet is launched, it
displays a list of popular international airports for which weather
information can be retrieved (see Figure 2). It also displays an exit
button to allow the user to exit the midlet.
Upon selecting an airport, a list of weather information services for
that airport is displayed (see Figure 3). A back button is also
displayed to allow the user to return to the airport menu. The user
then selects the weather information service he or she is interested
in and the midlet sends a SOAP request to the server to collect the
desired information. A SOAP response is returned, parsed by the
midlet, and the result is displayed on the screen. So how does all of
that work? See Listing 1 for the command Action() method.
The outer level of the commandAct ion() method checks to see what
component has been activated. We'll look at each of these four events
individually, beginning with the airport menu:
if ( dis == airportMenu && com == List.SELECT_COMMAND ) {
currentAirport = airportMenu.getSelectedIndex();
servicesMenu.setTitle( airports[ currentAirport ] + " weather" );
display.setCurrent( servicesMenu ); //display the list of services
When an airport is selected, we set the currentAirport variable, set
the title for the services menu to reflect the selected airport, and
display the services menu.
Next we'll look at the services menu. There are seven possible
weather services that can be retrieved: wind conditions, temperature,
pressure, humidity, sky conditions, visibility, and a complete
summary containing the six individual pieces of information:
else if ( dis == servicesMenu && com == List.SELECT_COMMAND ) {
String result = null;
int choice = servicesMenu.getSelectedIndex();
The first thing to do is to declare a String variable to store the
result of the service call that will be made. Next, determine which
service has been selected and store the index value in an integer
variable and perform a switch on that variable. The switch statement
can be seen in Listing 2. The first case retrieves a summary and the
other cases retrieve individual weather items. After the switch
statement, the results are displayed on the screen via an Alert
object.
Within each case statement in the switch block, the callSer vice()
method is used to handle the exchange of SOAP messages. See Listing
3).
Four essential things take place in this method. An HttpTran sport
object is created, a PrefixMap namespace is created for the SOAP
envelope, a SoapObject is created to represent the request, and the
request object is sent via the HttpTransport class's call() method.
The next else/if block checks to see if the back command has been
selected, in which case the list of airports is displayed:
else if ( com == backCommand ) {
display.setCurrent( airportMenu );
Finally, the exit command is checked to allow the application to be exited:
else if ( com == exitCommand ) {
destroyApp( true );
notifyDestroyed();
That's all there is to it. Download the source code to get the
details for the interface and then you are ready to build the midlet
interface, compile the code and access this weather service from a
J2ME phone using SOAP!
Conclusion
Web services are sweeping the industry and changing the face of
business. Mobile computing and wireless access to information at any
time, from anywhere, is an increasingly popular idea. The combination
of the two is explosive! In these two articles, we've explored
XML-RPC and SOAP as protocols for accessing Web services from
wireless devices. XML-RPC provides a highly-efficient, extremely
lightweight mechanism for invoking Web services that is ideal for
mobile and embedded devices. SOAP provides a slightly heavier
protocol with increased functionality and flexibility. Between these
two, an appropriate protocol will likely be found for any wireless
project.
Author Bios
Kyle Gabhart is the director of the Java Division of Objective
Solutions (www.objectsoln.com), a high-end engineering services
company based in Richardson, TX. Kyle is a prolific writer, with more
than a dozen technical articles and books to his name and he is the
original contributor of the kXML-RPC source code, which is now part
of the EhydraME platform.
java@objectsoln.com
Jason Gordon is an Associate Architect for Verizon's Technology
Integration and eInfrastructure group (www.verizon.com). He is a core
member of the KXML-RPC design team for EnhydraME and also serves as
Region 5 Telecommunications Chair for the National Society of Black
Engineers (www.nsbe.org).J
jaSontgordon@hotmail.com
Wireless Web Services with J2ME Part II, by Kyle Gabhart & Jason Gordon
WSJ Vol 02 Issue 02 - pg.48
Listing 1
public void commandAction( Command com,
Displayable dis ) { *
if ( dis == airportMenu &&
com == List.SELECT_COMMAND ) {
// An airport has been selected
}
else if ( dis == servicesMenu &&
com == List.SELECT_COMMAND ) {
// A weather service has been selected
}
else if ( com == backCommand ) {
// The back button returns to airport menu
}
else if ( com == exitCommand ) {
// The exit button exits the midlet
}//end if/else
}//end commandAction(Command, Displayable)
Listing 2
switch( choice ) {
case 0:
SoapObject obj = (SoapObject)
callService( currentAirport, "getSummary" );
if (obj != null ) {
result = "The weather at " +
obj.getProperty(0) + " is " +
obj.getProperty(3) + " with a " +
obj.getProperty(2) + " sky, and wind " +
obj.getProperty(1) + ". The humidity is " +
obj.getProperty(4) + ", the pressure is " +
obj.getProperty(5) + ", and visibility is " +
obj.getProperty(6) + ".";
}//end if (obj != null)
break;
case 1:
result = (String) callService( currentAirport,
"getHumidity" );
break;
case 2:
result = (String) callService( currentAirport,
"getPressure" );
break;
case 3:
result = (String) callService( currentAirport,
"getSkyConditions" );
break;
case 4:
result = (String) callService( currentAirport,
"getTemperature" );
break;
case 5:
result = (String) callService( currentAirport,
"getOb" );
break;
case 6:
result = (String) callService( currentAirport,
"getWind" );
break;
}//end switch();
//display the result
response.setString( result );
display.setCurrent( response );
Listing 3
private Object callService( int choice,
String methodName ) {
Object result = null;
try {
transport = new HttpTransport( serviceUrl,
soapAction + "#" + methodName );
transport.debug = true;
classMap = new ClassMap();
classMap.prefixMap = new PrefixMap(
classMap.prefixMap, "air", serviceNamespace );
transport.setClassMap( classMap );
request = new SoapObject( serviceNamespace,
methodName );
request.addProperty( "arg0",
airportCodes[ choice ] );
result = transport.call( request );
} catch( Exception e ) {
e.printStackTrace();
System.out.println( "Request: \n" +
transport.requestDump );
System.out.println( "Response: \n" +
transport.responseDump );
result = null;
}//end try/catch
return result;
}//end callService()
All Rights Reserved
Copyright © 2004 SYS-CON Media, Inc.
E-mail:
info@sys-con.com