Web Services using kSOAP
The focus of this article is to give a hands on walk-through using the kSOAP. Yes there are other available libraries/APIs for Web Service clients like the JSR 172 or Wing Foot. I've chosen kSOAP primarily because it does not have to be implemented by the vendor such as the case for JSR 172 and it is open source which you will see later is quite beneficial for patching any enhancements. If you do not know what Web Services are I recommend you do a search on Google and learn a little a bit about Web Services before continuing with this article. The remainder of this article will go through the installation and setup of both the Web Service client (J2ME and kSOAP). As well the installation setup of 2 Web Service Servers (independent of each other), this will be done with both "PHP with NuSOAP" and "Java, Tomcat (Catalina) with Apache SOAP".
Required Software
1. Sun Microsystem Wireless Toolkit 2.1, doesn't really matter which one considering kSOAP runs independent from the Toolkit version. 2. kSOAP from http://ksoap.objectweb.org/ (this article use the 1.x version) 3. Apache from http://www.apache.org/ 4. PHP http://www.php.net 5. NuSOAP ( SOAP library for PHP) http://dietrich.ganx4.com/nusoap/index.php 6. Tomcat http://jakarta.apache.org/tomcat/ 7. Java Standard Edition http://java.sun.com/ 8. Apache Soap http://ws.apache.org/soap/ It is assumed you have some familiarity with both Java and PHP, we will only briefly go through installation, for more detail installation instructions visit the listed website above..
Installation: PHP and NuSOAP
It is assumed you have access to a PHP server, to install NuSOAP download the latest from http://dietrich.ganx4.com/nusoap/index.php . In the past I have found the latest is usually still in CVS and not yet packaged for release. The version we are using version v0.6.6. (I believe the latest at the time of this writing is 0.6.7) To include NuSOAP into your PHP script use the standard include_once option and that is it, i.e.: include_once("nusoap"); Drop the following PHP Web Service server source code into your Apache enabled PHP server: [phptag] // Pull in the NuSOAP code require_once('nusoap.php'); // Create the server instance $server = new soap_server(); // Initialize WSDL support $server->configureWSDL('hellowsdl', 'urn:hello'); // Put the WSDL schema types in the namespace with the tns prefix $server->wsdl->schemaTargetNamespace = 'urn:hello'; // Register the method to expose $server->register('hello', // method name array('name' => 'xsd:string'), // input parameters array('return' => 'xsd:string'), // output parameters 'urn:hello', // namespace 'urn:hello#hello', // soapaction 'rpc', // style 'encoded', // use 'Says hello to the caller' // documentation ); // Define the method as a PHP function function hello($name) { return "Hello " . $name . "! from PHP/NuSOAP"; } // Use the request to (try to) invoke the service $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; $server->service($HTTP_RAW_POST_DATA); [/phptag] Now test it by calling the exact url the file resides in, for example I have my script in, click on the method and you will see the following:

PHP Web Service Server setup is now done.
Installation: Tomcat and Apache SOAP
It is assumed you have Java Standard Edition already installed. Download Tomcat ( http://jakarta.apache.org/tomcat/ ) and Apache Soap ( http://ws.apache.org/soap/ ) Tomcat is fairly simple to install, simply uncompress it and run [tomcat-home]\bin\startup.bat. You should see the Tomcat webpage at http://localhost:8080/ if not see the Tomcat site for help. Now decompress the Apache soap, grab the soap.war file and drop into the webapp There are 2 more things you need, JavaMail and JavaBeans Activation Framework extension jars. Download both of them from Sun and place the jars the CLASSPATH. To test this, go to the url http://localhost:8080/soap/ you should be able to access the admin page the rpcrouter page. Now compile the following HelloWorld.java program public class HelloWorld { private String greeting; public String hello(String name) { greeting = new String("Hello " + name + "! from Apache Soap"); return greeting; } } Create the following deployment descriptor xml file:
To deploy this drop the HelloWorld.class file into [tomcat-home]\webapps\soap\WEB-INF\classes Now at command line run the following command to deploy the HelloWorld Web Service: java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy c:/DeploymentDescriptor.xml Two other useful commands are: 1. java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list (this will list current deployed services) 2. java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy HelloWorld (this will undeploy the service) That is it the Apache SOAP HelloWorld Web Service Server is ready to go!
Installation: J2ME and kSOAP
Ok, now on to the client, start a new MIDlet project in the Sun Wireless Toolkit and drop the kSoap jar into the lib directory. Here is the client source code you need to use import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.io.*; import javax.microedition.io.*; import org.ksoap.*; import org.ksoap.transport.*; import org.ksoap.SoapObject; public class SimpleWebService extends MIDlet implements CommandListener { private Command exitCommand; // The exit command private Display display; // The display for this MIDlet // URL for PHP / NuSOAP private String phpUrl = ""; // URL for Apache SOAP private String apacheUrl = "http://localhost:8080/soap/servlet/rpcrouter"; public SimpleWebService() { display = Display.getDisplay(this); exitCommand = new Command("Exit", Command.SCREEN, 2); try { // Create new Soap Client, specifiy the Service and method to call SoapObject client = new SoapObject ( "urn:HelloWorld", "hello"); // Add the requied parameter, // if you look at either the PHP or Java server side code // one input parameter is required client.addProperty("name","J2MEBuilder.com"); // Make the Method Call HttpTransport ht = new HttpTransport(apacheUrl,"hello"); // Display the Apache SOAP result System.out.println("RESULT: " + ht.call(client)); // Set call to a different url ht.setUrl(phpUrl); // Display the PHP NuSOAP result System.out.println("RESULT: " + ht.call(client)); } catch (Exception ex) { System.out.println(ex); ex.printStackTrace(); } } public void startApp() { TextBox t = new TextBox("WebService Client MIDlet", "See Command Console for results", 256, 0); t.addCommand(exitCommand); t.setCommandListener(this); display.setCurrent(t); } public void commandAction(Command c, Displayable s) { if (c == exitCommand) { destroyApp(false); notifyDestroyed(); } } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }
Running the J2ME Client
This is nothing different from any other MIDlet, ensure that the 2 Web Service servers are running. You may have to change the URLs in the MIDlet code to suit yours, I'm using for the PHP Web Service and http://localhost:8080/soap/servlet/rpcrouter for the Apache SOAP Web Service. When you execute the MIDlet you should see the following in the console output window: The above example is dead simple but half the battle is the initial setup of the Web Service Client and Web Service Server(s). In the example, only simple types are being passed you may find it more difficult to pass Complex Types at least with language/scripts such as PHP that do not support collection classes commonly found in Java or objects that contain attributes that are objects as well. You will have to experiment on your own. Basic Authentication At least with kSOAP 1.x if you need Basic Authentication you will need to patch the HttpTransport Because Basic Authentication use Base64 you can re-use the org.kobjects.base64.Base64. Add the following patch // 2 New private attributes, required Basic Authentication inputs private String username; private String password; // Set Method public setBasicAuthCredentials(String username, String password) { this.username = username; this.password = password; } // Add Basic Authentication data to the HttpConnection if username // and password are not null connected = true; connection = (HttpConnection) Connector.open (url, Connector.READ_WRITE, true); if (this.username != null && this.password != null) { StringBuffer buf = new StringBuffer(this.username); buf.append(':').append(this.password); byte[] raw = buf.toString().getBytes(); buf.setLength(0); buf.append("Basic "); org.kobjects.base64.Base64.encode(raw, 0,raw.length, buf); connection.setRequestProperty("Authorization",buf.toString()); buf = null; } connection.setRequestProperty ("SOAPAction", soapAction); connection.setRequestProperty ("Content-Type", "text/xml"); connection.setRequestProperty ("Content-Length", ""+requestData.length); connection.setRequestProperty ("User-Agent", "kSOAP/1.0"); to use it just call the method ie: httpTransport.setCredentials("username","thepassword");
Other Patches
If you are interested in retaining a SESSION see the following Code Gallery http://www.j2mebuilder.com/content/codegallery/j2me_read_cookies.php If you are interested in making Blackberry HTTP Connection call see the following Code Gallery http://www.j2mebuilder.com/content/codegallery/http_connections_with_blackberry.php
Well there you go you should be able to know create Web Services using PHP or Apache SOAP and call them with a J2ME client using kSOAP. However, you should really ask yourself do you really need to use SOAP, even though it gives you standardize transport based on XML it doesn't come without a price. The main issue using web services with mobile devices is the over head of XML and parsing. Compare this SOAP response to just a string output response from a PHP script not using SOAP Hello J2MEBuilder.com! from PHP/NuSOAP In the mobile wireless world where network latency, number of bytes and network round-tripping is definitely a concern using SOAP takes up a lot more resources. Plus you need to take into account the extra room kSOAP takes up in the entire MIDlet jar. You could due away with the jar size problem if use JSR 172 but remember not all devices currently support that optional package. You should carefully evaluate if it is truly worth using Web Services, of course as technology advances along with wireless networks this will become less of a concern.. In the mean time you may want to build an extra layer on the server-side where it communicates with the WebServices using SOAP but communicates with the mobile devices with proprietary byte definition. Later when technology does improve you can SOAP enable the mobile clients and remove the extra layer. Don't forget other clients in the mean time can make use the Web Services like JavaTV, Desktop Clients, Applets and web sites.
Free Web Services
http://www.xmethods.net/ http://www.google.com/apis/ http://www.amazon.com/gp/browse.html/103-8460653-8915805?node=3435361
Web Services Resources
kSOAP - http://ksoap.objectweb.org/ JSR 172 J2ME Web Services Specification - http://www.jcp.org/aboutJava/communityprocess/review/jsr172/ http://www.wingfoot.com/products.jsp http://www-136.ibm.com/developerworks/webservices/ http://msdn.microsoft.com/webservices/ http://www.webservices.org Need Help? Need help with this article post a thread in the J2MEBuilder.com forum, http://www.j2mebuilder.com/forum/