Basic KSOAP Android Tutorial


This is a basic KSOAP Android tutorial - here I will show you how to get started with KSOAP on Android. As you may know, we often want to access Web services via hand-held devices, and most likely you will run into trouble parsing the WSDL and the SOAP messages. Since I come from a .NET background, once I started developing on Android, I realized how much work has been Visual Studio doing for me.

That thought took me to search for a framework or library to help me consume Web Services with Android. I ran into KSOAP2, which seemed like a good library, but unfortunately, very badly documented for most scenarios, like passing or returning complex objects, working with arrays of objects or even working with dates.



All of this I needed to find out by myself and this is why I decided to write this tutorial. So, let's begin.

Getting Started with KSOAP on Android


First things first, so you should now go ahead and download the KSOAP library from Sourceforge Google code (*UPDATE* thanks Freddy):
http://code.google.com/p/ksoap2-android/downloads/detail?name=ksoap2-android-assembly-2.4-jar-with-dependencies.jar&can=2&q=


Then copy and paste the KSOAP library in the folder where your Android project will reside. Open Eclipse, start a new Android Project, right-click on the project's name and choose Properties, like this:


The next thing you need to do is to Add the KSOAP .JAR into the Android Project:


Implementing KSOAP Marshal Interface



Another poorly documented spot in KSOAP: marshaling arguments. In KSOAP, you need to implement an interface called Marshal so that the XML parser would know how to serialize and deserialize objects you are trying to pass through the web service.

Strangely enough, object types like "double" and "Date" need to be manually marshaled! This is why I decided my code examples to show how to marshal dates and doubles. So here it goes:

package Marshals;

import java.io.IOException;

import org.ksoap2.serialization.Marshal;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
/**
* 
* @author Vladimir
* Used to marshal Doubles - crucial to serialization for SOAP
*/
public class MarshalDouble implements Marshal 
{


    public Object readInstance(XmlPullParser parser, String namespace, String name, 
            PropertyInfo expected) throws IOException, XmlPullParserException {
        
        return Double.parseDouble(parser.nextText());
    }


    public void register(SoapSerializationEnvelope cm) {
         cm.addMapping(cm.xsd, "double", Double.class, this);
        
    }


    public void writeInstance(XmlSerializer writer, Object obj) throws IOException {
           writer.text(obj.toString());
        }
    
}

Returning Array of Primitive Types with KSOAP



KSOAP until recently had an issue with returning an array of primitive types. With the new patch the issue is solved. If you haven't downloaded the newest version of
KSOAP available on GitHub, you can use the following snippet:

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
            SoapSerializationEnvelope envelope =
            new SoapSerializationEnvelope(SoapEnvelope.VER11);
            //envelope.dotNet = true;
            envelope.setOutputSoapObject(request);
            AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
        androidHttpTransport.call(SOAP_ACTION, envelope);

                KvmSerializable ks = (KvmSerializable)envelope.bodyIn;
                for(int i=0;i<ks.getPropertyCount();i++)
                {
                   ks.getProperty(i); //if complex type is present then you can cast this to SoapObject and if primitive type is returned you can use toString() to get actuall value.
                }

Web Service That Returns An Array of Objects With KSOAP



In my previous post, I wrote about an example of passing complex objects with KSOAP. In this post, I will write about returning arrays of objects with KSOAP.
If you want to know how to write a method that returns an array of complex objects, look at this code:
public static Category[] GetAllCategories()
    {
        String MethodName = "GetAllCategories";
        SoapObject response = InvokeMethod(URL,MethodName);
        return RetrieveFromSoap(response);
        
    }

Where the function InvokeMethod is :

public static SoapObject InvokeMethod(String URL,String MethodName)
    {
        SoapObject request = GetSoapObject(MethodName);
        SoapSerializationEnvelope envelope = GetEnvelope(request);
        return  MakeCall(URL,envelope,NAMESPACE,MethodName);
    }

GetSoapObject() and GetEnvelope() are:

public static SoapObject GetSoapObject(String MethodName)
    {
        return new SoapObject(NAMESPACE,MethodName);
    }
    public static SoapSerializationEnvelope GetEnvelope(SoapObject Soap)
    {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(Soap);
        return envelope;
    }

MakeCall() is :
/**
     * 
     * @param URL - The complete URL where the web service resides 
     * @param Envelope - The envelope to be passed
     * @param NAMESPACE - The web method namespace
     * @param METHOD_NAME - The method name
     * @return - SoapObject containing the resultset
     */
    public static SoapObject MakeCall(String URL, SoapSerializationEnvelope Envelope, String NAMESPACE, String METHOD_NAME)
    {
        AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
         try
            {
                androidHttpTransport.call(NAMESPACE + METHOD_NAME, Envelope);
                SoapObject response = (SoapObject)Envelope.getResponse();
                return response;
            }
         catch(Exception e)
         {
             e.printStackTrace();
             
         }
         return null;
    }

KSoap Android Web Service Tutorial With Sample Code



A few months ago I was engaged into working with Android and I wanted to make an application that will communicate with the server via .NET SOAP web services, but I soon found out that I will need a library to do the "donkey work for me". Unfortunately, what Visual Studio was doing for me behind the scenes when importing WSDL document, was not present in Android. That means that, I would either parse the WSDL XML myself, or use an external library. After little search, I came up to KSOAP, which looked like a promising library. But soon I got into lot of trouble to make it work.
Partly because there was no complete tutorial with the WHOLE sample WORKING code for passing complex objects as parameters and/or arrays as return values (read this post for returning arrays of objects with KSOAP ), I spent many hours debugging exceptions which were filled with nulls and poor documentation in first place.

Therefore I decided to publish the code I managed to make it work, so many lives will be saved :-) hopefully. I almost forgot about the idea of publishing my code, but today I got some e-mails from some of the Google groups where I was begging for help when I was developing the Android application. So, tortured developer souls, a complete working code for working with the KSOAP library for Android:

Scenario:
We will assume that we want to write a web service that retrieves the details about a given Category by its Id. So, in .NET, the service signature would be:


[Web Method]
public Category GetCategoryById(Category C);