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);

CsharpGears: New class for Dynamic Discovery of Stored Procedure Parameters

Yesterday I wrote a new class in the CSharpGears Framework. It is called ParameterExtractor and it's purpose is to discover the parameters of a given stored procedure and retrieve them in a collection. This class utilizes the method DeriveParameters in order to discover the parameters of the procedure and therefore, it can be only used with SQL Server unfortunately, but since SQL Server is quitte often a choice for database solution, this class might come in handy. The class also has caching capabilities, which can help saving performance since DeriveParameters method causes a roundtrip to the database, and you certainly don't want to have two accesses to the database for each query. Because of that, it uses static caching and keeps the list of parameters in a collection for further reuse.  I have to admit that I am not certain about the thread safety of this operation, it is possible that a lock statement is required as a critical region.
  My intention is to combine the ParameterExtractor and integrate it with my N-tier architecture, so that it will help me automate the parameter adding process from my business objects to the stored procedures. The framework already supports the reverse process, namely to map the datareader's columns into a list of business objects ( you can read my post about Object relational mapping if you are interested). I hope that soon my project architecture will contain clean, separated code which is also easy to write, due to the generics of C#.
  However, one should be aware of the limitations of this class, it only works with SQL Server, and of course, it needs more memory to keep the stored procedure parameters, but its greatest adventage is that it is possible to write a code that will examine a business object and it will decide alone which attributes are needed to be mapped with which parameters - AUTOMATICALLY :).

"I am thinking that I am lazy..." - David Byrne

CsharpGears is Free and Open Source Framework



I use this opportunity to emphasize the fact that the CsharpGears Framework is absolutely Free and Open source, meaning anyone who wants can download the framework and use it for free, or even make changes in the code, but he/she can't claim he/she invented it.
Recently a reader told me he wanted to use my framework but he was interested in making changes in the source code, and then I noticed that I havent put the full version available for download, so I did that immediately.
And anyone who has some kind of trouble using the CsharpGears framework, may feel free to contact me, I will be happy to help. If anyone has a constructive suggestion or wish for next releases, post it as a suggestion.

"There is nothing like a dream to create the future" - Victor Hugo