Enterprise J2ME Developing Mobile Java Applications [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Enterprise J2ME Developing Mobile Java Applications [Electronic resources] - نسخه متنی

Michael Juntao Yuan

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید



16.2 Introducing kSOAP


To build Web Services clients on J2ME devices, we first need a J2ME-compatible SOAP parser. Most standard Java SOAP libraries (such as the Apache Axis and Java Web SDK) are too heavy for small devices. The open source kSOAP project runs on all J2SE and J2ME platforms, including the MIDP. Built on top of the kXML parser, the entire kSOAP library is only 42 KB. However, as a trade-off for the lightness, kSOAP does not support the entire SOAP specification. It supports the most commonly used SOAP features and is sufficient for most Web Services that are currently available. Currently, almost all major kSOAP applications and tools are based on kSOAP release v1.2, which supports a core subset of SOAP 1.2 features. Although kSOAP v2.0 was released in November 2002, new features are still being developed and debugged. I recommend you use kSOAP v1.2 for important real-world applications but keep an eye on kSOAP v2.0. For developers, kSOAP v2.0 is easy once you understand the key concepts and programming models in v1.2. For the above reasons, we focus on kSOAP v1.2 in this chapter and give a programming tutorial for kSOAP v2.0 in Section 16.6.


16.2.1 What Is SOAP Parsing?


Every generic XML parser with namespace support understands SOAP messages and can extract information from them. In theory, we can always extract text information from a SOAP document using a generic XML parser and then convert those text strings to Java data objects when we need to use them. For example, the statement


int i = Integer.parseInt("123");

converts a text string "123" to an integer value 123. But such manual conversion burdens application programmers. Extracting Java data objects directly from a SOAP document provides a better approach. Enter the SOAP parser.

A SOAP parser is built on a generic XML parser with special type-mapping and text data-marshaling mechanisms. A SOAP parser understands the data-type information in SOAP messages and automatically converts the SOAP elements to Java data objects. The parser's real value is that it makes SOAP serialization and deserializationand the entire wire protocol-transparent to object-oriented developers. The programmer just feeds Java objects into a SOAP writer, sends the message, waits for the server response, and then reads Java objects directly from the SOAP parser.


16.2.2 Simple Parsing Example Using kSOAP


Using kSOAP to make simple RPC calls is very easy. Listing 16.3 demonstrates how to make a SOAP call to Google's Web Services interface to obtain the spell suggestion of a phrase. The basic steps are the following:


Prepare the arguments to pass to the remote method. We instantiate a SoapObject object and add call arguments using the addProperty() method.

Prepare the call transport. We instantiate a HttpTransport object with the URL to the SOAP interface.

Make the remote method call. We pass the assembled SoapObject object (from step 1) to the HttpTransport object's call() method. The return value from the remote service is available as the return value of the call() method.


Listing 16.3. Spell check using Google


// The URL of the SOAP interface
String endPointURL = "http://api.google.com/search/beta2"
String licenseKey = "Register with Google to get it";
public String spellCheck (String query) throws Exception {
// Prepare request SOAP message in a memory object
SoapObject method = new SoapObject("urn:GoogleSearch",
"doSpellingSuggestion");
method.addProperty("key", licenseKey);
method.addProperty("phrase", query);
// Prepare SOAP RPC call object.
HttpTransport rpc = new HttpTransport(endPointURL, "\"\");
// Google uses 1999 SOAP standards.
ClassMap cm = new ClassMap(Soap.VER10);
rpc.setClassMap (cm);
// Conduct RPC call through HTTP and
// directly get results
String spellSugg = (String) rpc.call (method);
return spellSugg;
}


16.2.3 How the call() Method Works


The HttpTransport.call() method is local to us. But behind the scenes, it does a lot of remote work.


The call() method first serializes the SoapObject object to a SOAP request message with proper namespaces. For the Google spell check example, the SOAP request is shown below:


<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<doSpellingSuggestion xmlns="urn:GoogleSearch"
id="o0" SOAP-ENC:root="1">
<key xmlns=" xsi:type="xsd:string">...</key>
<phrase xmlns=" xsi:type="xsd:string">
phon
</phrase>
</doSpellingSuggestion>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

It submits the request to the endPointURL through normal HTTP.

It retrieves the response SOAP message. We show Google's response here.


<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:doSpellingSuggestionResponse
xmlns:ns1="urn:GoogleSearch"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:string">phone</return>
</ns1:doSpellingSuggestionResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

At last, it marshals the response to a Java object and returns that object. In this case, it is a Java string phone.


To fully understand how the call() method works, we need to look at its source code.


16.2.4 kSOAP Message Transport


Listing 16.4 shows the source code of the HttpTransport class. The HttpTransport class is currently the only message transport class in kSOAP. It is based on the very limited MIDP HTTP implementation. If you need HTTPS, cookie-aware HTTP, authentication-aware HTTP, or support for other network protocols, you have to plug in your own implementation.

Note

In kSOAP v1.2, there is no support for SOAP headers. As we can see in the HttpTransport class, SoapFault handling is very poor. kSOAP v2.0 will provide API to access the header. We can then insert our own code to handle SoapFault.

Listing 16.4. The HttpTransport class


package org.ksoap.transport;
import java.io.*;
import javax.microedition.io.*;
import org.kxml.*;
import org.kxml.io.*;
import org.kxml.parser.*;
import org.ksoap.*;
public class HttpTransport {
String url;
String soapAction = "\"\";
SoapEnvelope requestEnvelope = new SoapEnvelope ();
SoapEnvelope responseEnvelope = new SoapEnvelope ();
HttpConnection connection;
OutputStream os;
InputStream is;
InputStreamReader reader;
private boolean connected = false;
public HttpTransport () { }
public HttpTransport (String url, String soapAction) {
this.url = url;
this.soapAction = soapAction;
}
public void setUrl (String url) {
this.url = url;
}
public void setSoapAction (String soapAction) {
this.soapAction = soapAction;
}
public void setClassMap (ClassMap classMap) {
requestEnvelope.setClassMap (classMap);
responseEnvelope.setClassMap (classMap);
}
public void call () throws I0Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream ();
XmlWriter xw =
new XmlWriter (new OutputStreamWriter (bos));
requestEnvelope.write (xw);
xw.flush ();
bos.write ('\r'); bos.write ('\n');
byte [] requestData = bos.toByteArray ();
bos = null; xw = null;
try {
connected = true;
connection = (HttpConnection) Connector.open (url,
Connector.READ_WRITE, true);
connection.setRequestProperty ("SOAPAction", soapAction);
connection.setRequestProperty ("Content-Type", "text/xml");
connection.setRequestProperty (
"Content-Length", "+requestData.length);
connection.setRequestProperty ("User-Agent", "kSOAP/1.0");
connection.setRequestMethod(HttpConnection.POST);
os = connection.openOutputStream ();
os.write (requestData, 0, requestData.length);
os.close ();
requestData = null;
is = connection.openInputStream ();
reader = new InputStreamReader (is);
XmlParser xp = new XmlParser (reader);
responseEnvelope.parse (xp);
} finally {
if (!connected) throw
new InterruptedIOException ();
reset ();
}
}
public Object call (SoapObject method) throws IOException {
requestEnvelope.setBody (method);
call ();
if (responseEnvelope.getBody () instanceof SoapFault)
throw((SoapFault)responseEnvelope.getBody ());
return responseEnvelope.getResult ();
}
public void call (XmlIO request, XmlIO result)
throws IOException {
requestEnvelope.setBody (request);
responseEnvelope.setBody (result);
if (responseEnvelope.getBody () instanceof SoapFault)
throw((SoapFault)responseEnvelope.getBody ());
}
public void reset () {
connected = false;
if (reader != null) {
try { reader.close (); }
catch (Throwable e) {}
reader = null;
}
if (is != null) {
try { is.close (); }
catch (Throwable e) {}
is = null;
}
if (connection != null) {
try { connection.close (); }
catch (Throwable e) { }
connection = null;
}
}
}


16.2.5 kSOAP Stub Generators


The Google spell check example is very easy to code by hand. But things get complex quickly when the remote service returns complex data objects. It is a pain to sort through a long WSDL document and figure out the exact SOAP interface. For complex services, automatically generated client stubs from WSDL files prove useful. For example, both Apache Axis and Sun Java Web Services Developer Pack offer WSDL2Java tools.

However, kSOAP is a small footprint library, not a complete Web Services toolkit. It lacks the tools to automatically generate client stubs. Fortunately, several J2ME IDEs provide such tools. kSOAP is adopted by IBM WebSphere Studio Device Developer (WSDD, a J2ME IDE based on Eclipse), SunONE Studio and CodeWarrior Wireless Studio as their default mobile Web Services client library. All of them offer GUI wizards that ask you the URL to the WSDL file and automatically generate the stubs into your current project source directory.

Note

The kSOAP client generator in SunONE Studio is only available through a module for the enterprise edition.


/ 204