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

The class that we want to work with has 3 properties: CategoryId, Name and Description. But in order to use it with KSOAP, we need to implement the KvmSerializable interface (Code below is in Java):


package CommonObjects;

import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

/**
 * 
 * @author Vladimir
 * Represents the Category object. KvmSerializable interface needs to be 
 * implemented for performing serialization.
 */
public class Category implements KvmSerializable
{
    public int CategoryId;
    public String Name;
    public String Description;
    
    public Category(){}
    

    public Category(int categoryId, String name, String description) {
        
        CategoryId = categoryId;
        Name = name;
        Description = description;
    }


    public Object getProperty(int arg0) {
        
        switch(arg0)
        {
        case 0:
            return CategoryId;
        case 1:
            return Name;
        case 2:
            return Description;
        }
        
        return null;
    }

    public int getPropertyCount() {
        return 3;
    }

    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
        switch(index)
        {
        case 0:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "CategoryId";
            break;
        case 1:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "Name";
            break;
        case 2:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "Description";
            break;
        default:break;
        }
    }

    public void setProperty(int index, Object value) {
        switch(index)
        {
        case 0:
            CategoryId = Integer.parseInt(value.toString());
            break;
        case 1:
            Name = value.toString();
            break;
        case 2:
            Description = value.toString();
            break;
        default:
            break;
        }
    }
}

All methods in this class are members of the KvmSerializable Interface, and are used to tell KSOAPhow to map the properties, read them and write them.

Now, the actual web service call:

public void WebServiceCallExample()
    {
        String NAMESPACE = "http://vladozver.org/";
        String METHOD_NAME = "GetCategoryById";
        String SOAP_ACTION = "http://vladozver.org/GetCategoryById";
        String URL = "http://192.168.1.3/VipEvents/Services/CategoryServices.asmx";
        
        SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
        
        /*
         * Create Category with Id to be passed as an argument
         * 
         * */
        Category C = new Category();
        C.CategoryId = 1;
        
        /*
         * Set the category to be the argument of the web service method
         * 
         * */
        PropertyInfo pi = new PropertyInfo();
        pi.setName("C");
        pi.setValue(C);
        pi.setType(C.getClass());
        Request.addProperty(pi);
        
        /*
         * Set the web service envelope
         * 
         * */
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(Request);
        
        envelope.addMapping(NAMESPACE, "Category",new Category().getClass());
        AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
        /*
         * Call the web service and retrieve result ... how luvly <3
         * 
         * */
        try
        {
            androidHttpTransport.call(SOAP_ACTION, envelope);
            SoapObject response = (SoapObject)envelope.getResponse();
            C.CategoryId =  Integer.parseInt(response.getProperty(0).toString());
            C.Name =  response.getProperty(1).toString();
            C.Description = (String) response.getProperty(2).toString();
            TextView tv = (TextView)findViewById(R.id.TextView01);
            tv.setText("CategoryId: " +C.CategoryId + " Name: " + C.Name + " Description " + C.Description);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

In order to use this code, make sure that you replace the first three variables in this method with your own. NOTE: The SOAP_ACTION could actually be computed as NAMESPACE + METHOD_NAME

In the lines about the property info, I show how to actually pass a Category class complex object to KSOAP.

PropertyInfo pi = new PropertyInfo();
        pi.setName("Category");
        pi.setValue(C);
        pi.setType(C.getClass());
        Request.addProperty(pi);

Regarding the return type, if your web method returns a complex object (such as ours), you need to tell KSOAP how to handle the response. That is done with the following code:

envelope.addMapping(NAMESPACE, "Category",new Category().getClass());

This part of the code is the actual retrieval of the response:
androidHttpTransport.call(SOAP_ACTION, envelope);
            SoapObject response = (SoapObject)envelope.getResponse();
            C.CategoryId =  Integer.parseInt(response.getProperty(0).toString());
            C.Name =  response.getProperty(1).toString();
            C.Description = (String) response.getProperty(2).toString();

For further reading, see my post about returning an array of complex objects with KSOAP

334 comments:

«Oldest   ‹Older   201 – 334 of 334
SeeSharpWriter said...

This is important because your response is a complex object which encapsulates another complex object. KSOAP does not know by default how to handle the encapsulated [data] tags (object).

Ak said...

Hi

I got an error after using the asp webservice,in an emulator "connection Refused"

so what should i do....?

Anonymous said...

What if I pass a custom object named "Account" to the web service (and I already have an Account class declared the way you coded your Category class in android), so I still need to declare that Account class in the web service?

dewmal said...

Help me for this

SoapObject so = new SoapObject(NAMESPACE, METHOD_RELEASEVEHICLE);
PropertyInfo pi = new PropertyInfo();
pi.name = "vehicleassingpark"; // name of the parameter in your dotnet variable
pi.type = Vehicleassingpark.class;
pi.setValue(vehicleassingpark);
so.addProperty(pi, vehicleassingpark);

SoapSerializationEnvelope envelope3 = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope3.bodyOut = so;
envelope3.dotNet = false;

envelope3.addMapping(NAMESPACE, "vehicleassingpark", Vehicleassingpark.class);
envelope3.setOutputSoapObject(so);

HttpTransportSE ht3 = new HttpTransportSE(URL);
ht3.setXmlVersionTag("");
ht3.debug = true;
ht3.call(SOA_RELEASEVEHICLE, envelope3);
SoapObject response = (SoapObject) envelope3.getResponse();
vehicleassingpark = new Vehicleassingpark(response);



and this is the code for complex object
public class Vehicleassingpark extends implements KvmSerializable {

private static final String TAG = Vehicleassingpark.class.getName();
private Date relseaedtime;
protected VehicleassingparkPK vehicleassingparkPK;
private double exceedpayments;
private boolean isrealeased;
private Barcodecard barcodecard;
private Vehicle vehicle;
private Carpark carpark;
private List lledvehicleList;

// has code i cannot add them because of comment char limit
}

dewmal said...

this my code i got error

23:31:37.868 3520 ERROR AndroidRuntime FATAL EXCEPTION: main
23:31:37.868 3520 ERROR AndroidRuntime java.lang.NullPointerException
23:31:37.868 3520 ERROR AndroidRuntime at java.io.Writer.write(Writer.java:152)
23:31:37.868 3520 ERROR AndroidRuntime at org.kxml2.io.KXmlSerializer.startTag(KXmlSerializer.java:420)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:639)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:683)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeProperty(SoapSerializationEnvelope.java:671)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:640)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:624)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:681)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.serialization.SoapSerializationEnvelope.writeBody(SoapSerializationEnvelope.java:597)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.SoapEnvelope.write(SoapEnvelope.java:192)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.transport.Transport.createRequestData(Transport.java:107)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:119)
23:31:37.868 3520 ERROR AndroidRuntime at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:95)
23:31:37.868 3520 ERROR AndroidRuntime at com.duineth.vpark.mob.main.ws.WebService.releaseVehicle(WebService.java:169)
23:31:37.868 3520 ERROR AndroidRuntime at com.duineth.vpark.mob.main.model.MobileAppController.releaseVehicle(MobileAppController.java:190)
23:31:37.868 3520 ERROR AndroidRuntime at com.duineth.vpark.mob.activity.ReleaseVehicleActivity.btReleaseOnClickAction(ReleaseVehicleActivity.java:105)
23:31:37.868 3520 ERROR AndroidRuntime at com.duineth.vpark.mob.activity.ReleaseVehicleActivity.access$000(ReleaseVehicleActivity.java:31)
23:31:37.868 3520 ERROR AndroidRuntime at com.duineth.vpark.mob.activity.ReleaseVehicleActivity$1.onClick(ReleaseVehicleActivity.java:64)
23:31:37.868 3520 ERROR AndroidRuntime at android.view.View.performClick(View.java:2501)
23:31:37.868 3520 ERROR AndroidRuntime at android.view.View$PerformClick.run(View.java:9107)
23:31:37.868 3520 ERROR AndroidRuntime at android.os.Handler.handleCallback(Handler.java:587)
23:31:37.868 3520 ERROR AndroidRuntime at android.os.Handler.dispatchMessage(Handler.java:92)
23:31:37.868 3520 ERROR AndroidRuntime at android.os.Looper.loop(Looper.java:130)
23:31:37.868 3520 ERROR AndroidRuntime at android.app.ActivityThread.main(ActivityThread.java:3835)
23:31:37.868 3520 ERROR AndroidRuntime at java.lang.reflect.Method.invokeNative(Native Method)
23:31:37.868 3520 ERROR AndroidRuntime at java.lang.reflect.Method.invoke(Method.java:507)
23:31:37.868 3520 ERROR AndroidRuntime at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
23:31:37.868 3520 ERROR AndroidRuntime at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
23:31:37.868 3520 ERROR AndroidRuntime at dalvik.system.NativeStart.main(Native Method)

Balamurugan said...

hi SeeSharp..

thanks for your ksoap android web service tutorial

I have one doubt

In the Client side we send the value of CategoryId as object, given below..

Category C = new Category();
C.CategoryId = 1;

PropertyInfo pi = new PropertyInfo();
pi.setName("C");
pi.setValue(C);
pi.setType(C.getClass());
Request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);

My doubt is
HOW can i get the value of CategoryId in Server side from the object C..

public Category GetCategoryById(Category C)

please clear my doubt... Weather server side need KvmSerializable is implement in the Category class...

Anonymous said...

I am trying to get your code to work with a .NET SOAP web service running in .NET 3.5.

First, using KSOAP 2.6 AndroidHttpTransport doesn't seem to be a part of the package anymore. Was it replaced by HttpTransportSE?

Second, My web service call gets:
W/System.err( 399): SoapFault - faultcode: 'soap:Server' faultstring: 'Server w
as unable to process request. ---> Object reference not set to an instance of an
object.' faultactor: 'null' detail: org.kxml2.kdom.Node@40718870

Here is the code I'm using:
public void WebServiceCallExample(String NAMESPACE, String URL)
{
String METHOD_NAME = "GetCategoryById";
String SOAP_ACTION = NAMESPACE + "/" + METHOD_NAME;

SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);

// Create Category with Id to be passed as an argument
Category C = new Category();
C.CategoryId = 1;

// Set the category to be the argument of the web service method
PropertyInfo pi = new PropertyInfo();
pi.setName("C");
pi.setValue(C);
pi.setType(C.getClass());
Request.addProperty(pi);

// Set the web service envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);

envelope.addMapping(NAMESPACE, "Category",new Category().getClass());
org.ksoap2.transport.HttpTransportSE androidHttpTransport = new org.ksoap2.transport.HttpTransportSE(URL);
// Call the web service and retrieve result ... how luvly <3
Log.d(TAG,"Ready to call");
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
Log.d(TAG,"Back from the call");
SoapObject response = (SoapObject)envelope.getResponse();
C.CategoryId = Integer.parseInt(response.getProperty(0).toString());
C.Name = response.getProperty(1).toString();
C.Description = (String) response.getProperty(2).toString();
Log.d(TAG,"CategoryId: " +C.CategoryId + " Name: " + C.Name + " Description " + C.Description);
}
catch(Exception e)
{
e.printStackTrace();
}
}

Anonymous said...

I'm trying to call a Java web service(GetCategoryById(Category C))) but getting an error Unknown element C. I have mentioned below the web service code and android client code.
Can anyone please let me know if I'm missing something ? Thanks.


Java web service:

public class CategoryWebSvc {
public Category GetCategoryById(Category C){
Category cat = new Category();
cat.CategoryId = C.CategoryId;
return cat;
}
}

web svc android client code

SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
Category C = new Category();
C.CategoryId = 1;

PropertyInfo pi = new PropertyInfo();
pi.setName("C");
pi.setValue(C);
pi.setType(C.getClass());
Request.addProperty(pi);

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
//envelope.dotNet = false;
envelope.setOutputSoapObject(Request);

envelope.addMapping(NAMESPACE, "Category",new Category().getClass());
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);

try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject response = (SoapObject)envelope.getResponse();
C.CategoryId = Integer.parseInt(response.getProperty(0).toString());
}
catch(Exception e)
{
e.printStackTrace();
}

OUTPUT

WEB SERVICE admin console

==== INPUT ====
content-type: text/xml
user-agent: kSOAP/2.0
connection: close
soapaction: http://systinet.com/wsdl/websvc/CategoryWebSvc
content-length: 452






1





==== OUTPUT ====
content-type: text/xml;charset=UTF-8
soapaction: ""





e:Server
Unknown element C


org.idoox.xmlrpc.MessageProcessingException: Unknown element C
at org.idoox.wasp.wsdl.SOAPMethodInfo$RequiredElements$Invocation.notNillElement(SOAPMethodInfo.java:1033)
at com.systinet.wasp.server.adaptor.JavaInvoker.fillCallParamsXml(JavaInvoker.java:1162)
at com.systinet.wasp.server.adaptor.JavaInvoker.beginInvoke(JavaInvoker.java:491)
at com.idoox.wasp.server.adaptor.JavaAdaptorImpl.beginInvoke(JavaAdaptorImpl.java:63)

Anonymous said...

The output on admin console got truncated for some reason so I mentioning it again.
I can see the input parameters being sent to the web service but it's failing during de-serialization
==== INPUT ==== http://local:8080/wasp/CategoryWebSvc/
content-type: text/xml
user-agent: kSOAP/2.0
connection: close
soapaction: http://systinet.com/wsdl/websvc/CategoryWebSvc
content-length: 452






1





==== OUTPUT ==== http://local:8080/wasp/CategoryWebSvc/ =========
content-type: text/xml;charset=UTF-8
soapaction: ""





e:Server
Unknown element C


org.idoox.xmlrpc.MessageProcessingException: Unknown element C
at org.idoox.wasp.wsdl.SOAPMethodInfo$RequiredElements$Invocation.notNillElement(SOAPMethodInfo.java:1033)
at com.systinet.wasp.server.adaptor.JavaInvoker.fillCallParamsXml(JavaInvoker.java:1162)
at com.systinet.wasp.server.adaptor.JavaInvoker.beginInvoke(JavaInvoker.java:491)
at com.idoox.wasp.server.adaptor.JavaAdaptorImpl.beginInvoke(JavaAdaptorImpl.java:63)

Anonymous said...

Hi
How can i use your code with https URL. when I'm using this code with my https URL, I'm getting error as "Not trusted sever certificate".
Please help me..

Hassan Mehmood said...

Hi SeeSharpWriter,

I am trying to make KSOAP work with my .NET asmx web service.

I am passing byte[] to .NET WebServive (MTOM based service)


I have the latest build of KSOAP2 too (2.6.0)

its giving me exception
"org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT null@1:0 in java.io.InputStreamReader@46eb0ae0) "

I wonder what i am doing wrong.

If you want to see the code on both ends, let me know.

Please reply urgently. Thanks in Advance

laxman said...

hi please any one solve my problem i am not getting how to chech user id and password
String res=checklogin( id2,pas2, accesseusername2, accesspassword2);


if(res!=null){
Toast.makeText(getApplicationContext(),"logged sucess laxman", Toast.LENGTH_LONG).show();
Intent in=new Intent(ProjectActivity.this,employee.class);
startActivity(in);
}

else{
Toast.makeText(getApplicationContext(),"ur failed", Toast.LENGTH_LONG).show();;


}
}catch (Exception e) {
Toast.makeText(getApplicationContext(),e.getMessage(), Toast.LENGTH_LONG).show();
}

}



});

}
protected String checklogin(String id2, String pas2,
String accesseusername2, String accesspassword2) {

SoapObject request = new SoapObject(NAMESPACE, OPERATION_NAME);
request.addProperty("username",id2);
request.addProperty("password",pas2);
request.addProperty("accessusername", accesseusername2);

request.addProperty("acesspassword", accesspassword2);

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;

envelope.setOutputSoapObject(request);

HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS);

httpTransport.debug=true;
try

{

httpTransport.call(SOAP_ACTION, envelope);


//SoapPrimitive result=(SoapPrimitive) envelope.getResponse();

SoapObject result=(SoapObject)envelope.getResponse();
//String resultdata=result.getProperty(0).toString();
String re=result.toString();

}


catch(SocketException ex)
{
Log.e("Error : " , "Error on soapPrimitiveData() " + ex.getMessage());
ex.printStackTrace();
}
catch (Exception e) {
Log.e("Error : " , "Error on soapPrimitiveData() " + e.getMessage());
e.printStackTrace();
}

return re;

Moath Fararjeh said...

very very thanks for post .... but please can you write your full webService code ...

Moath Fararjeh said...

thaaaaaaaaaaaaaaaaaaaanks ,,, great job

please .. can you send me your webservice code??
i need it

Vaibhav said...

This is very nice tutorial its working but i am getting
Server was unable to read request. ---> There is an error in XML document (1, 797). ---> Input string was not in a correct format.
this exception i am sending request with 29 parameters i also tried using complex class object bt it is also not working plz help me..

Anonymous said...

This is very nice tutorial its working but i am getting
Server was unable to read request. ---> There is an error in XML document (1, 797). ---> Input string was not in a correct format.
this exception i am sending request with 29 parameters i also tried using complex class object bt it is also not working plz help me..
its urgent...

Anonymous said...

Thanks a lot for the above help this was life saving.

HappieHippie said...

Thanks for the tutorial. But, when I try to send complex type objects, the server receives null. Any ideas?

~ChInNa~ said...

String tagid = str;// "AB6614CD";
PropertyInfo pi = new PropertyInfo();
/*pi.setName("tagid");
pi.setValue(tagid);
pi.setType(String.class);
request.addProperty("tagid",tagid);*/

request.addProperty("arg0", tagid);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
//envelope.dotNet = true;
HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS);
try {
httpTransport.call(SOAP_ACTION, envelope);
Object response = envelope.getResponse();
// textView.setText(response.toString());
test = response.toString();
String test1 = test+".jpg";
String fileURL = "http://sposter.smartag.my/images/"+test1;
URL url = new URL(fileURL);
URLConnection conexion = url.openConnection();
conexion.connect();

int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);

InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/"+test1);

byte data[] = new byte[1024];

long total = 0;

while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}

output.flush();
output.close();
input.close();

} catch (Exception exception) {
// textView.setText(exception.toString());
test = exception.toString();
}
return null;

I get null pointer exception. Please help.

pakis said...

hi
if my web service is in this style how it will have to set up the java code in order to work





int

int
int

dateTime





actually i have use 1 KvmSerializable for the BloOdPressure for the 2 field and the other values jjust make a simple request. but it's not working :) i have to create something else in order to work? it return me null. i don't get anything else. i could provide all the code for more details

Gurvinder Singh said...

I am getting this response :-

anyType{Response=anyType{ErrorCode=0; ErrorDescription=anyType{}; Data=anyType{jobs=anyType{job=anyType{number=624; name=57Jones Road; }; job=anyType{number=463; name=Actual Building Demo Site; }; job=anyType{number=465; name=Building Demo Site; }; job=anyType{number=414; name=Employee Record; }; job=anyType{number=576; name=JPC; }; job=anyType{number=446; name=Landscaping; }; job=anyType{number=409; name=New Zealand Primary School; }; }; }; }; }


I tried to parse it using the category class but no success Please help How can I parse it ..

pakis said...

adding on my previous post because something happen and can not display the code :)

soap:Body>
AddPlethysmogram xmlns="http://tempuri.org/">
PatientID>int
values>string
SampleRate>int
DateTimeStamp>dateTime
/AddPlethysmogram>
</soap:Body

and the java code is the follow

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("PatientID", "8");

Category i1=new Category();
i1.setDistolic(Integer.parseInt("100"));
i1.setSistolic(Integer.parseInt("100"));

PropertyInfo pi=new PropertyInfo();
pi.setName("BloodPressure");
pi.setValue(i1);
// pi.setType(i1.getClass());
request.addProperty(pi); request.addProperty("DateTimeStamp",datetime);

Jeet said...

Hi SeeSharp,

Thank for posting this nice artical. I am new this Android development, could you please help me help me solving my issue mentioned here

http://stackoverflow.com/questions/9633733/generation-of-complex-soap-envelope-in-accordance-with-oasis-ws-security-specifi

rachana said...

Hi,
Your article helps me a lot..
I have one problem that once i put all values in object and then i passed that object to web service using propertyinfo.

But am not able to retrieve that object where my web service is located.
Error am getting is "java.lang.RuntimeException :Cannot serialize :obj :com.project.gui.derived_spec@40530ed8"

where "obj" is the object which am trying to pass through propertyinfo.

plz help me to solve this prob..

Amer said...

Hi,

I tried to use this code for sending complex data type from android to wcf. I just copied this code and create class Category and method which has Category as parameter in C# WCF:

[DataContract]
[Serializable]
public class Category
{
public int CategoryId { get; set; }
public String Name { get; set; }
public String Description { get; set; }
}

public string FormatCategory(Category C)
{
return C.CategoryId + " " + C.Name + " " + C.Description;
}

I test this method and it works in WCF. I also test android communication with wcf and tried to call method without parameters and it also works.


But when I try to send complex parameter to method (like Category) it doesn't work. .NET debugger show null reference exception. It seems like Category isn't properly send to WCF.


What could be a problem here?


Thanks in advance

Amer said...

Any opinions?

jayku said...

I am using Axis2 on the server side and I get runtime exception when I call the webservice that returns by class object which is written as per the example here. The part of the exception is below, can someone pls help

2012-03-28 00:33:56,717 ERROR [http-8080-2] receivers.RPCMessageReceiver - org.apache.axis2.AxisFault: Property 'property' in bean class 'com.hcda.content.RssFeedVo'is not readable.
java.lang.RuntimeException: org.apache.axis2.AxisFault: Property 'property' in bean class 'com.hcda.content.RssFeedVo'is not readable.
at org.apache.axis2.databinding.utils.BeanUtil.getPropertyQnameList(BeanUtil.java:276)
at org.apache.axis2.databinding.utils.BeanUtil.getPullParser(BeanUtil.java:72)
at org.apache.axis2.rpc.receivers.RPCUtil.processResponse(RPCUtil.java:98)
at org.apache.axis2.rpc.receivers.RPCUtil.processResponseAsDocLitWrapped(RPCUtil.java:456)
at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:153)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)...

Vina said...

@GurvinderSingh: Try using this.Not sure it might work.

SoapObject l_result = (SoapObject) l_envelope.bodyIn;
Log.i("Tag", "l_result " + l_result);

g_no_of_Elements = l_result.getPropertyCount();

for (int l_elements = 0; l_elements < g_no_of_Elements; l_elements++) {
l_soap_object = (SoapObject) l_result.getProperty(l_elements);
l_number = l_soap_object.getProperty("number").toString();
l_name = l_soap_object.getProperty("name").toString();


}

Anonymous said...

I want to send a list of Objects (List) to my .NET Web Service..

android said...

I have problem with :
envelope.addMapping

Hossein khalaj said...

Hi,, Thanks for your sharing knowledge ...
I did test your solution but i have still problem, i get null value in my service ,,,

What can i do?

Thanks :)

SeeSharpWriter said...

I would turn on the debug mode to see what happens. Start off with a simple web service.

Erick Gallani said...

Hi.

First thank you for this exmple and the code.

Second I'm having a problem trying to do this, I'm getting the following error:

SoapFault - faultcode: 'a:DeserializationFailed' faultstring: 'The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:pCliente. The InnerException message was 'Error in line 1 position 354. Element 'http://tempuri.org/:pCliente' contains data from a type that maps to the name 'http://tempuri.org/:ClienteVO'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'ClienteVO' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.' faultactor: 'null' detail: null

Looking to the message its look like the problem is in my WCF, but I have no idea what could be.

Do you know anything about it?

Thank you

Anonymous said...

Hi ,
Thanks for posting the code

Anonymous said...

Hi,
could any one please help me im getting error as SoapFault - faultcode: 'Server.userException' faultstring: 'No such operation 'Method Name'' faultactor: 'null....

Thanks in advance

Chaminda said...

Awesome tutorial, lot of problems sorted out from this thanks.

125f86ee-a98c-11e1-9ed7-000f20980440 said...

Hey,

i've some problems with this tutorial.

My first question is: Do you use the same "Category" Class in the Webserver or what methods does it have?

COuld you show me how i have to design my Category Class at the webservice (i use a java Webservice with Tomcat 7 and Java 1.6)

Thanks

Sana said...

Hi....
awesome tutorial See sharp...please help me to sort the error below.....

SoapFault - faultcode: 'soapenv:Server.userException' faultstring: 'org.xml.sax.SAXException: Bad types (class java.lang.String -> class java.sql.Date)' faultactor: 'null' detail

Sergio said...

Hello all, i have just een this post today, and i have one cuestion. Do you have a similar example but making a call to a WSSecurity?I need to use a svc service whit usernametoken identifier. Colud you help me? sercelaya@gmail.com

SeeSharpWriter said...

I am sorry Sergio, I have no knowledge about that. Maybe someone else does, so they can contact you.

Anonymous said...

Hey,

i tested your tutorial and have some issues, could you help me on stackoverflow?

http://stackoverflow.com/questions/10999763/ksoap2-and-kvmserializable-how-to-send-complex-objects-like-stringarrays

Tanks :-)

Arun Srinivasan said...

Ok... I feel there can be a slight improvement that can be done to the code on the whole.

First - implementing the KVMSerializable interface makes less sense as the methods implemented are not used.

lets say we get the properties like this from the response object.

object.property = typecast(response.getProperty(i).toString())

Since we already implement the setProperty method with all the necessary type casting and stuff in place, I found that calling the setProperty method with the index and the response.getProperty did the trick.

This especially works for nested classes that need to be assigned with the help of the parent classes set method. In this case, you can pass the value as lets say

parentclass.setProperty(index, response.getProperty(index))

in the setProperty method, this can be typecasted as a soapObject, which can again be passed to another method for assignment to the child objects properties.

Further enhancements can be done for sending in advanced requests to a webservice by using the get methods implemented as a result of KVMSerializable interface.

This is just my suggestion.

PS: Sorry I cannot share from my network.

SeeSharpWriter said...

Thank you, Arun. Your improvements certainly make sense and are much appreciated!

Anonymous said...

Hi,so if I'm receiving a complex object from a web service written in C# firstly I should write in Java an equal class as the one I'm receiving and then use the .mapping you mentioned above right?

Anonymous said...

Hi In case I'm receiving a big object with alot of fields from my wcf is it okay if my class that implements the kvmSerializable has only the field that i find important? or is it going to be a mapping problem?

Anonymous said...

Hi In case I'm receiving a big object with alot of fields from my wcf is it okay if my class that implements the kvmSerializable has only the field that i find important? or is it going to be a mapping problem?

Anonymous said...

Really helpfull post,thx a lot :)

mohammed zarqa said...
This comment has been removed by the author.
mohammed zarqa said...

i am having a problem executing this code firstly to get result i changed this line SoapObject response = (SoapObject)envelope.getResponse();

into>>>

SoapObject response = (SoapObject)envelope.bodyIn;

and after that this line
C.CategoryId = Integer.parseInt(response.getProperty(0).toString());

generates the following error
java.lang.NumberFormatException: unable to parse 'anyType{CategoryId=10055; Name=my name;Description=my Desc;}' as integer

any help plz???

mohammed zarqa said...

i got it the correction is as follows

SoapObject response = (SoapObject)envelope.bodyIn;
SoapObject c2 = (SoapObject)response.getProperty(0);
tv.setText("Category" + c2.getProperty(0));

Kevin Flynn said...

Hi,
My implementation works ok, I have a request as follows:


222.0
INFOCAS
20120525
003621126CB
2179.3
TIT
S11211
PDH
M
CCA25052020
301
PRPIA






I receive this response:




02
Object reference not set to an instance of an object.





I saw the WCF log and found that all my fields reach the WCF with zero values!!!
Can someone help me about this?

Thanks in advance.

Juan

Martosfre said...

Excelent post!!!

pinto said...

i am not getting anything on screen it is blank ps help

pinto said...

org.xmlpull.v1.xmlpullparserexception unexpected type position text system.invalidoperation..@4:1in java.io.inputstreamreader
NOW I AM GETTING THIS ERROR

SeeSharpWriter said...

@Kevin Flynn, I have never tried this out on WCF, but if you manage to make it work, please let us know

SeeSharpWriter said...

@mohammed zarqa, thanks for sharing! I hope someone will find this useful

siamesePretzels said...

THANK YOU SO MUCH!!! I had been stuck on the problem of complex types in ksoap for 4 days now. I read your article... created the class, put in my own data, and BOOM!!! Everything worked literally first try. I could almost cry I'm so happy. I've probably put in 40 hrs of work or more on this issue. Again... THANK YOU SO MUCH!

SeeSharpWriter said...

@siamesePretzels I am glad it saved much of your life :)

Gürcan said...

Thank you for your great post! It is very helpful.

SeeSharpWriter said...

@Gürcan You are welcome. It really means to me.

Loki said...

Thanks. This tutorial was very helpful.

Anonymous said...

hi, its very helpfull post.

I've one question thought: do You have an idea how to add additional field in Category class.

I'd be an image, so in a webserwis this field would by a base64Binary, but we have

PropertyInfo.STRING_CLASS;
PropertyInfo.INTEGER_CLASS;,

but dont have base64Binary...

Anonymous said...

i want to add image filed in this Category class... in webserwice it would be a base64binary field.

How to do this?

Ive found this in ksoap2 page, but dont know how to implement in your code. Can anyboy help me out?



Can I send (and receive) objects of type byte[] with kSOAP? Yes, there are two options. One option is to to create an intermediate SoapPrimitive object, encapsulating the byte array:

new SoapPrimitive (Soap.ENC, "base64", Base64.encode (myByteArray));

The SoapPrimitive object can be used in conjunction with SoapObjects or the getProperty() method of KvmSerializable. For receiving byte arrays, the corresponding base64 encoded string contained in the SoapPrimitive object must me decoded using the method Base64.decode().

The other option is to use the optional MarshalBase64 class in the package org.ksoap.marshal, available separately in the download section. In most cases, it should be activated using the like shown in the example below:

ClassMap cm = new ClassMap (); new MarshalBase64.register (cm);
myHttpTransport.setClassMap (cm);

svesda said...

Hi Vladimir,

What is the format of the data returned by the web services in this tutorial?

I am trying to parse the XML data structure and not quite sure how to do so. The data returned looks like this:
Pasifika DrumsDistinctive to the sound of Cook Islands music is the full and resonating drumbeat.http://.../Demo.aspxhttp://.../2.jpg

Could you suggest what I need to do to be able to parse this XML string.

What would be some other options for the data to be passed from the web services to Android app, if 1 object with a few attributes needs to be passed or a list of such objects.

Is the XML structure a good option?

Thanks in advance.
Lara

SeeSharpWriter said...

Hi Lara,

good questions! The web services return a Category object in XML format.

The XML you have probably pasted is showed as plain text in the comment of the blog - perhaps blogger strips the tags.

Anyway, even today I find parsing objects with KSOAP bit difficult and messy. I would recommend that you use a simple string with a defined delimeter:

"Pasifika Drums###Distinctive to the sound of Cook Islands music is the full and resonating drumbeat###http://.../Demo.aspx###http://...2.jpg"

where ### is the delimeter. Then simply tokenizing the string will allow you to grab all the data that is sent by the server. I believe this is far simpler (and more primitive) approach, but will save you much of your time.

svesda said...

Hi,

what does your web service return in this tutorial? I am getting an exception array out of bounds when trying to read the responce into an object.

svesda said...

Hi Vladimir, sorry just realised that there are 2 pages of comments. Have read your reply, thanks, still need some more help understanding.

Yes the tags were removed when I posted it :( I kinda don't really understand what it looks like - the returned by SOAP Category object. My project partner is creating the web services and I am working on the mobile app side. What he is returning to me is this http://hyperdisc.unitec.ac.nz/project04/InteractiveCultureCustom/WebService.asmx?op=xmlTest, valid IDs are 1 and 2. Could you please tell me if this looks right. I think he is passing a String instead of an object. Is that right?

Later on I will have to get an array of such objects and the object will have a list links, so I think if I get your example working it would be efficient to use.

Thanks again for your help

svesda said...

Hi again,

have figured it out, thanks for your help.

Wendigo Miguel said...

Hi, I get this error when I calling a WS with a parameter of type Planet.

SoapFault - faultcode: 'soapenv:Server' faultstring: 'Unknow type {http://ws.solar.com}Planet' faultactor: 'null' detail: org.kxml2.kdom.Node@405e9500

What's the problem?

In the server I get:
org.apache.axis2.AxisFault: Unknow type {http://ws.solar.com}Planet


In this line:
SoapObject response = (SoapObject)envelope.getResponse();

Thanks in advance.

The Planet type is:
- Integer
- Integer
- Integer
- String

svesda said...

Wendigo Miguel,

Is this your namespace http://ws.solar.com ?
You should be able to open your namespace and URL links via browser, see example below

private final String NAMESPACE = "http://www.webserviceX.NET/";
private final String URL = "http://www.webservicex.net/ConvertWeight.asmx";

SeeSharpWriter said...

Wendigo Miguel, is your web service in .NET ?

mike z said...

Very useful post.It helped me in couple months ago.Now i have to send a complex object.This seems to be really difficult for me.I'm stuck for quite a while.Can you point me to the right direction?

SeeSharpWriter said...

Hey mike z ! You might check this link:

http://seesharpgears.blogspot.com/2010/10/web-service-that-returns-array-of.html

Basically you need to make the complex object "as simple as possible", avoid encapsulating complex objects within complex objects (and arrays). Make sure that you have the same complex object class in .NET and Android

mike z said...

I've done so in the past!What i'm asking is how to send not receive a complex object

SeeSharpWriter said...

Mike z, the code in this current post is written deliberately so that it sends a complex object (instance of the Category class) to a web service method called GetCategoryById. Pay attention to these few lines of code:

/*
* Set the category to be the argument of the web service method
*
* */
PropertyInfo pi = new PropertyInfo();
pi.setName("C");
pi.setValue(C);
pi.setType(C.getClass());
Request.addProperty(pi);

mike z said...

I've done exactly what you are suggesting.That's why i feel desparate.I've also been experimenting with the .implicitTypes=true and .addAdorments(false).I should mention that i also set the name space of the object(I used the wcftestclient to see the soap message it sends and under this object it has 2 different namespaces)I'm pretty sure i'm messing something there because i get an object reference to null on the server side

mike z said...

would it help if i'd post here the soap message that is sent by the wcftestclient?

mike z said...

ok I solved it.It was really a hard ridle.It was about the namespaces afterall.But not on the client side,on the server side.So i know that this tutorial focuses on the client side,i'll just provide the link that literally saved me hope it will help someone else.

http://stackoverflow.com/questions/12846149/passing-objects-to-wcf-soap-service-from-android-using-ksoap2-it-sends-and-rece

navidonline said...

Can anyone solve my problem?

http://stackoverflow.com/questions/13379418/how-to-send-string-array-in-soap-request-to-webservice

Chris Boehm said...

I know this is an old blog, but I've run into a somewhat unique situation.

I need to send a complex object that contains byte[] as one of it's properties. The problem lies in the getPropertyInfo method of the object...

"
public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info) {
// TODO Auto-generated method stub
switch (index)
{
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "MyString";
break;
case 1:
info.type = ????? //wtf goes here
info.name = "MyByteArray";
break;
}
"

I know if you were sending byte[] as a separate parameter you would use mySoapObject.addProperty( "MyByteArray", new SoapPrimitive(SoapEnvelope.ENC,"base64", myByteArray );

The problem is, there is no way (as far as I can tell) to specify a property as a base64 primitive type inside of the complex object that implements Marshal, KvmSerializable.

Do you know of any way to do this?

SeeSharpWriter said...

@Mike z, thank you for posting your solution!

@Chris, I don't know really as for now, but if I find out, I will post the solution for you.

Anonymous said...

Is there any other way to connect android app to mySQL database using web services other than using KSOAP?

SeeSharpWriter said...

Of course, you just expose your data against an URL in XML format, make a GET request from Android and parse the XML...

As a matter of fact, I would recommend that over KSOAP

Dario said...

Hi, Im a newbie on Android Development just 3 days now working on it. I think this is a great tutorial, but I noticed its been a while since you published this. So you think this is still "valid"? Do you think is a better way now?

Thanks,

Anonymous said...

Thanks a lot for extremely useful article.
Your post worked as aspirin as i was having headache in using KSOAP.

SeeSharpWriter said...

Hi Dario, yes it is valid . It is a shame though... Consuming a Web service should be easy, and this is a complete opposite of that, but at least it works.

SeeSharpWriter said...

Thank you, I was going through the same headaches and I am glad that at least I eased someone else's pain with KSOAP :)

I dono tell said...

I have tried the same code but I did not get any value nor any error. What may be the problem and my service is running perfectly because i have tested accesing in dotNET application but in android I am unable. what may be the problem ?

Can any one please tell me?

Anonymous said...

Thanks for this tutorial, it rescued me!

Benjamin

Michal said...

you are the KSOAP angel! :D Thanks for your tutorials. Documentation is terrible.

Mohamed Labraiki said...

Hello , i hava been trying to consume a .net webservice ( just the helloworld method to test first ) i'm using a code similar to yours , but without adding paramter to request ( i don't need that for helloworld) i used the same code to consume perfectly a webservice for temparature conversion. but when i used it for the webservice of the company where i'm doing my internship i have a problem at : aht.call(SOAP_ACTION,envelope);
i catch an exception here : org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG
i tried many things but without result , and my webservice details are right ! can u help me please ?

Anonymous said...

how to pass parameters to the web service method in android?
I am using .net web service in android and want to call the method such as public void SelectP(String sPUID,List headers). how to call this method by getting string from the edit text box in android. I am using KSOAP. Please help me on this.

Miguel Otero said...

Hello, first of all thank you for your ksoap tutorials :) they have been helping me a lot with my coding.

If you have a complex type that has other complex attributes (imagine that your Category class has a java.sql.Date attribute), is it neccesary to serialize it in a special manner? In my case, I have a .NET Web Service that has this operation:

public Trip AddTrip(Trip trip, Guid idUser)
{
TripDAO dao = new TripDAO();
return dao.NewTrip(trip, idUser);
}

In order to call this operation, I need to create a Trip object, which has this attributes:

private System.Guid _ID;

private System.Guid _ID_USER;

private System.DateTime _InitDate;

private System.DateTime _EndDate;


In Android I have this code:

String NAMESPACE = "http://tempuri.org/";
String METHOD_NAME = "AddTrip";
String SOAP_ACTION = "http://tempuri.org/IDataBaseService/AddTrip";
String URL = "http://156.35.95.102:6060/DataBaseService.svc";

String initDate = initYear + "-" + initMonth + "-" + initDay + "T00:00:00";
String endDate = endYear + "-" + endMonth + "-" + endDay + "T00:00:00";

Trip trip = new Trip();
trip.InitDate = initDate;
trip.EndDate = endDate;

SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);

PropertyInfo pi = new PropertyInfo();
pi.setName("trip");
pi.setValue(trip);
pi.setType(trip.getClass());
Request.addProperty(pi);
Request.addProperty("idUser", user_id);

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);
envelope.addMapping(NAMESPACE, "Trip", Trip.class);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject response = (SoapObject)envelope.getResponse();
//response.getName();
}

When I run the program, it throws the following error:

The InnerException message was 'Error in line 1 position 342. Element 'http://tempuri.org:trip' contains data of the 'http://tempuri.org:Trip' data contract. The deserializer has no knowledge of any type that maps to this contract.

Hope you can help me on this.

Anonymous said...

this is what i'm looking for . Thaks.

Amritpal Singh said...

Hii,
I want to see the WSDL code for the corresponding web service class.Can you post it please....

BoredTechie said...

Great Article..
But Still some scenario is left..
What if I have a complex data type within the complex datatype..
and
What If I have an array of complex data type within a complex data type..

This is exactly the problem I am suffering from..
I think I am the only person in this world whose facing this issue..

SomeBody lease help :((((

Ashraf said...

To all those .NET developers out there, to make this work with the WCF webservice add xmlserializerformat

[ServiceContract(Namespace = "http://yournamespace/yourservice")]
[XmlSerializerFormat]
public interface yourService
{

[OperationContract]
string GetData(int value);

[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);

// TODO: Add your service operations here
[OperationContract]
User receiveObjectMethod(User user);


}

samyak shah said...

I have to pass data over a String wcf service like
a method in my wcf service name

String feedbk(Feedbk feedbk),
i have make class implements it with kvmserailizable through Ksoap2 library. Its not dotnet service. I have passed data like

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("stopfeedback");
pi.setValue(lm_ans);
pi.setType(String.class);
request.addProperty(pi);

add it in envelope and make a HttpTransportSE call.
in the response it neither add data to service nor make any call and show "anytype{}" without any parameters in response.
Can anybody help me? Its urgent. Thanks in advance

nalcantara said...

Hi, My reponse wsdl :





1
cuenta1
clave2


2
cuenta2
clave2






please . help me
my error is : java.io.IOException: unknown format (magic number bbef)
at java.util.zip.GZIPInputStream.(GZIPInputStream.java:101)
at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:182)

Arun Ps said...

Hi all,

I get the error when I try to get the response as SoapObject, but when i try to get as Object it works fine....My return value is in xml format.

java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive cannot be cast to org.ksoap2.serialization.SoapObject

Unknown said...

Hi SeeSharpWriter,e
At first thank you for useful post.
I'm working on an android project that sends some data to .Net web service(C#). Server sends xml string to response and I serialized objects by SimpleXML Serialization.(http://simple.sourceforge.net/home.php) a simple class like this:

@Root(name="root")
public class Example {

@Element(name="message")
private String text;

@Attribute(name="id")
private int index;

public Example() {
super();
}

public Example(String text, int index) {
this.text = text;
this.index = index;
}

public String getMessage() {
return text;
}

public int getId() {
return index;
}
}
Because this class serialized in web service and fields named like this.
(@Element(name="message")
private String text;)

Everything works OK. But now I want to send an array of "Example" object to web service. I searched a lot in Google and find your post.
Now I have 2 question:
1. Is there any way to map object's fields to a name instead of number like: index---> id @Attribute(name="id")
2. Can I send an array of complex object to web service?

Thanks in advance

ucci said...

Thank A LOT for this post!

velmurugan murugesan said...

When i tried to do this i got "AndroidHttpTransport cannot be resolved to a type" error..Help me

Anonymous said...

thanks man .. great example

Anonymous said...

It really works greatly in my app.....

thanx for such a nice tutorial...........

henry cumbicus rivera said...

Hola, muy buen tutorial y buenos aportes.
Mi pregunta es, cómo hago para recibir dos valores que regresa el metodo del WS? uno es un list y el otro es un double.
el mismo método regresa ambos tipos. Ayuda por favor.
muchas gracias.

Melissa Lall said...

Hi I'm trying to pass a list of complex objects to .net webservice.
Can someone assist.

mut Tonny said...

great tutorial... thanx big time.. though i had to write the webservice... bt alll worked fine...

python connolly said...

Hi I am having trouble parsing parameters. Here is my Android code:
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;


public class WebService {
//Namespace of the Webservice - can be found in WSDL
private static String NAMESPACE = "http://tempuri.org/";
//Webservice URL - WSDL File location
private static String URL = "http://84.51.246.251/ttms/remoteaccess.asmx";
//SOAP Action URI again Namespace + Web method name
private static String SOAP_ACTION = "http://tempuri.org/RemoteLogin";
//Method Name
private static String METHOD_NAME = "RemoteLogin";

public static boolean invokeLoginWS(String userName,String passWord, String METHOD_NAME) {
boolean loginStatus = false;
// Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// Property which holds input parameters
PropertyInfo unamePI = new PropertyInfo();
// Set Username, error:The method setName(String) is undefined for the type PropertyInfo
unamePI = "username";
// Set Value, error:The method setValue(String) is undefined for the type PropertyInfo
unamePI.setValue(userName);
// Set dataType, error:The method setType(Class) is undefined for the type PropertyInfo
unamePI.setType(String.class);
// Add the property to request object, error:The method addProperty(PropertyInfo, Object) in the type SoapObject is not applicable for the arguments (PropertyInfo)
request.addProperty(unamePI);

PropertyInfo passPI = new PropertyInfo();
//Set Password, error:The method setName(String) is undefined for the type PropertyInfo
passPI.setName("password");
//Set dataType, error The method setValue(String) is undefined for the type PropertyInfo
passPI.setValue(passWord);
//Set dataType, errorThe method setType(String) is undefined for the type PropertyInfo
passPI.setType(String.class);
//Add the property to request object, errorThe method addProperty(PropertyInfo, Object) in the type SoapObject is not applicable for the arguments (PropertyInfo)
request.addProperty(passPI);
// Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
//set to true or null objects will give errors
envelope.dotNet = true;
// Set output SOAP object
envelope.setOutputSoapObject(request);
// Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

try {
// Invoke web service
androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope);
// Get the response
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
// Assign it to boolean variable variable
loginStatus = Boolean.parseBoolean(response.toString());

} catch (Exception e) {
//Assign Error Status true in static variable 'errored'
CheckLoginActivity.errored = true;
e.printStackTrace();
}
//Return booleam to calling object
return loginStatus;
}
}

Max said...

With your solution i have the problem that the webserver says in the response:

soapenv:Server' faultstring: 'Unknow type {NAMESPACE}Entry' faultactor: 'null' detail: org.kxml2.kdom.Node

do you know the solution?

BR

Max said...

My Service is a java axis2 webservice but i don't know the Unknow type message

kasi lingam said...
This comment has been removed by the author.
kasi lingam said...

My Dot net Web Service was like this below & don't know how to call it



int

string


string


string




Albert Andrada said...

Really Nice Information,Thank You Very Much For Sharing.
Web Development Company

Jitendra singh said...

it is very nice information this blog
website designing company in india

morga said...

hi, i have a problem with data complex, but i want send a array to my WS, i like that anyone can help me with a example or explain as using the interface KvmSerializable,

example: int size[ ] = [1, 3, 5, 6, 8, 10];

PropertyInfo sizeVector= new PropertyInfo();
sizeVector.setName("size");
sizeVector.setValue(size);

thanks very much

Nataniel Soares said...

and when I have a complex type within another complex type?

Craig Cervo said...

One, of possibly many, reasons for error. This error is returned by the server hosting the web service. The server will have returned an HTTP status code of 5xx and this text "SoapFault - faultcode: 'soapenv:Server.userException' faultstring: 'org.xml.sax.SAXException: operation description is missing parameter description!' faultactor: 'null' detail: org.kxml2.kdom.Node@8961db2".
What it means is "The method you referenced in the service you referenced does not support a parameter of the type you passed in your call." I had this problem because I miss read the wsdl file for the service and thought the method I was calling required a parameter when in fact it didn't.
Check your code. Check the wsdl file for the service. Make sure your code matches the information in the wsdl file.

Yatika Dhingra said...

fantastic job on writing this…
Soap n noodle 80:20
Crude oil
glycerine
palm acid oil
sunflower acid oil
soya acid oil
rice fatty acid
soap stock
rice acid oil
mauha acid oil
palm kernel fatty
palm fatty hydonated
soap sac raps
Bath soda
Bath soap
pitch oil

Yatika Dhingra said...

Very useful article about Absolute great. Thanks.
Online Business Directory

Lama-Chan said...

Hi, i tried your tutorial but nothing happend when i run it :(

is there a way to contact you like i send you email so you can see my code and tell me what i did wrong?

Cuz im really confused i dont think i did something wrong but its not working.

and i really need it urgently.

thanks for helping.

AceZed ITSolution said...

Nice Information you have written here. Really Great Stuff. I keep it bookmark for our future purpose.

We are also Web development Company in India who provide the services in Android App Development in Nagpur , SEO Company in Nagpur , Ecommerce Website Development in Nagpur. Visit Us today

AceZed IT Solution

Malkhazi said...

how to pass xml as parameter?

POST /WayBillService/WayBillService.asmx HTTP/1.1
Host: services.rs.ge
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/save_waybill"





string
string
xml






import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpsTransportSE;
import java.net.URISyntaxException;

public class MainActivity extends AppCompatActivity {

private static final String METHOD_NAME = "save_waybill";
private static final String NAMESPACE = "http://tempuri.org";
private static final String URL = "https://services.rs.ge/WayBillService/WayBillService.asmx?WSDL";
final String SOAP_ACTION = "http://tempuri.org/save_waybill";

TextView tv;
StringBuilder sb;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
String[] params = new String[]{};
new MyAsyncTasc().execute(params);
setContentView(tv);
}

class MyAsyncTasc extends AsyncTask {
@Override
protected String doInBackground(String... params) {
try {

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("su","s22:12345678910");
request.addProperty("sp","123456");
String str1=""+"\n";
str1+="1149251011"+
"address 1address 2"+
"12345678910AAA111"+
"10"+
"21"+
""+
"0goods 114121.0214001"+
"0goods 2112.810.45285.8002"+
"0goods 3121.83.6004"+
"";
java.net.URI uri = null;
try {
uri = new java.net.URI(URL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
request.addProperty("waybill", str1);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpsTransportSE httpTransport= new HttpsTransportSE(uri.getHost(), 443, uri.getPath(), 60000);
httpTransport.call(SOAP_ACTION, envelope);
SoapObject result =(SoapObject) envelope.bodyIn;
return result.toString();
} catch (Exception e) {
return "Error:\n" + e.getMessage();
}
}
@Override
protected void onPostExecute(final String result) {
tv.setText(result);
}
}
}

returns error!
save_waybillResponse{save_waybillResult=anyType{RESULT=anyType{STATUS=-102; SUB_WAYBILLS=anyType{}; GOODS_LIST=anyType{}; }; }; }

and should return the following xml

0218846296

01202672875goods 114121.0214001
01202672876goods 2112.81.45285.800201202672877goods 3121.83.6004

0210118767

Malkhazi said...

must replace <- on < to get the xml text
String str1="<-?xml version=\"1.0\" encoding=\"utf-8\"?>"+"\n";
str1+="<-WAYBILL><-SELER_UN_ID>1149251<-/SELER_UN_ID><-ID>0<-/ID><-TYPE>1<-/TYPE><-STATUS>1<-/STATUS>"+
"<-START_ADDRESS>address 1<-/START_ADDRESS><-END_ADDRESS>address 2<-/END_ADDRESS>"+
"<-DRIVER_TIN>12345678910<-/DRIVER_TIN><-CAR_NUMBER>AAA111<-/CAR_NUMBER>"+
"<-CHEK_DRIVER_TIN>1<-/CHEK_DRIVER_TIN><-TRANSPORT_COAST>0<-/TRANSPORT_COAST>"+
"<-TRAN_COST_PAYER>2<-/TRAN_COST_PAYER><-TRANS_ID>1<-/TRANS_ID>"+
"<-GOODS_LIST>"+
"<-GOODS><-ID>0<-/ID><-W_NAME>goods 1<-/W_NAME><-UNIT_ID>14<-/UNIT_ID><-QUANTITY>12<-/QUANTITY><-PRICE>1.02<-/PRICE><-AMOUNT>14<-/AMOUNT><-BAR_CODE>001<-/BAR_CODE><-/GOODS>"+
"<-GOODS><-ID>0<-/ID><-W_NAME>goods 2<-/W_NAME><-UNIT_ID>1<-/UNIT_ID><-QUANTITY>12.81<-/QUANTITY><-PRICE>0.4528<-/PRICE><-AMOUNT>5.8<-/AMOUNT><-BAR_CODE>002<-/BAR_CODE><-/GOODS>"+
"<-GOODS><-ID>0<-/ID><-W_NAME>goods 3<-/W_NAME><-UNIT_ID>1<-/UNIT_ID><-QUANTITY>2<-/QUANTITY><-PRICE>1.8<-/PRICE><-AMOUNT>3.6<-/AMOUNT><-BAR_CODE>004<-/BAR_CODE><-/GOODS>"+
"<-/GOODS_LIST><-/WAYBILL>";

and following xml
<-STATUS>0<-/STATUS><-ID>218846296<-/ID>
<-GOODS_LIST>
<-GOODS><-ERROR>0<-/ERROR><-ID>1202672875<-/ID><-W_NAME>goods 1<-/W_NAME><-UNIT_ID>14<-/UNIT_ID><-UNIT_TXT /><-QUANTITY>12<-/QUANTITY><-PRICE>1.02<-/PRICE><-AMOUNT>14<-/AMOUNT><-BAR_CODE>001<-/BAR_CODE><-A_ID /><-STATUS /><-VAT_TYPE /><-/GOODS>
<-GOODS><-ERROR>0<-/ERROR><-ID>1202672876<-/ID><-W_NAME>goods 2<-/W_NAME><-UNIT_ID>1<-/UNIT_ID><-UNIT_TXT /><-QUANTITY>12.81<-/QUANTITY><-PRICE>.4528<-/PRICE><-AMOUNT>5.8<-/AMOUNT><-BAR_CODE>002<-/BAR_CODE><-A_ID /><-STATUS /><-VAT_TYPE /><-/GOODS>
<-GOODS><-ERROR>0<-/ERROR><-ID>1202672877<-/ID><-W_NAME>goods 3<-/W_NAME><-UNIT_ID>1<-/UNIT_ID><-UNIT_TXT /><-QUANTITY>2<-/QUANTITY><-PRICE>1.8<-/PRICE><-AMOUNT>3.6<-/AMOUNT><-BAR_CODE>004<-/BAR_CODE><-A_ID /><-STATUS /><-VAT_TYPE /><-/GOODS>
<-/GOODS_LIST>
<-WAYBILL_NUMBER>0210131857<-/WAYBILL_NUMBER>

Malkhazi said...

request.addProperty("su", params[1]);
request.addProperty("sp", params[2]);

//------------------ SoapObject
SoapObject waybill1 = new SoapObject("", "WAYBILL");
SoapObject goods1 = new SoapObject("", "GOODS");
SoapObject good_list1 = new SoapObject("", "GOODS_LIST");
waybill1.addProperty("SELER_UN_ID", 1149251);
waybill1.addProperty("ID", 0);
waybill1.addProperty("TYPE", 1);
waybill1.addProperty("STATUS", 1);
waybill1.addProperty("START_ADDRESS", "START_ADDRESS");
waybill1.addProperty("END_ADDRESS", "END_ADDRESS");
waybill1.addProperty("DRIVER_TIN", "61007004242");
waybill1.addProperty("CAR_NUMBER", "AAA000");
waybill1.addProperty("CHEK_DRIVER_TIN", 1);
waybill1.addProperty("TRANSPORT_COAST", 0);
waybill1.addProperty("TRAN_COST_PAYER", 2);
waybill1.addProperty("TRANS_ID", 1);

goods1.addProperty("ID", 0);
goods1.addProperty("W_NAME", "W_NAME");
goods1.addProperty("UNIT_ID", 1);
goods1.addProperty("QUANTITY", 2);
goods1.addProperty("PRICE", 1);
goods1.addProperty("AMOUNT", 2);
goods1.addProperty("BAR_CODE", "1");

good_list1.addProperty("GOODS", goods1);

goods1 = new SoapObject("", "GOODS");
goods1.addProperty("ID", 0);
goods1.addProperty("W_NAME", "W_NAME2");
goods1.addProperty("UNIT_ID", 1);
goods1.addProperty("QUANTITY", 4);
goods1.addProperty("PRICE", 1);
goods1.addProperty("AMOUNT",4);
goods1.addProperty("BAR_CODE", "2");

good_list1.addProperty("GOODS", goods1);

waybill1.addProperty("GOODS_LIST", good_list1);
SoapObject wib_send = new SoapObject("", "waybill");
wib_send.addProperty("WAYBILL", waybill1);
request.addProperty("waybill", wib_send);

Anonymous said...

IService1.vb Code is below:-
------------------------------

Function TestwithArgum(db As Message) As String


Public Class Message
Private m_Fname As String = ""
Private m_Lname As String = ""
Private m_Age As String = ""

Public Property Fname As String
Get
Return m_Fname
End Get
Set(value As String)
m_Fname = value
End Set
End Property

Public Property Lname As String
Get
Return m_Lname
End Get
Set(value As String)
m_Lname = value
End Set
End Property

Public Property Age As String
Get
Return m_Age
End Get
Set(value As String)
m_Age = value
End Set
End Property


End Class


Service1.svc.vb:-
-----------------
Public Function TestwithArgum(db As Message) As String Implements IService1.TestwithArgum
Dim Ftname As String
Dim Ltname As String
Dim age As String
Dim FinalData As String
Ftname = db.Fname
Ltname = db.Lname
age = db.Age
FinalData = Ftname + Ltname + age
Return FinalData
End Function

---------------------------------------------------------------------

Anonymous said...

here is my android coding....

public class MainActivity extends AppCompatActivity {

public String resulData;
public String s1,s2,s3;

public EditText Text1,Text2,number,revtxt;
Button Send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Text1=(EditText)findViewById(R.id.edittxt1);
Text2=(EditText)findViewById(R.id.editText2);
number=(EditText)findViewById(R.id.editText3);
revtxt=(EditText)findViewById(R.id.revtxt);
Send=(Button)findViewById(R.id.sendbtn);

s1=Text1.getText().toString();
s2=Text2.getText().toString();
s3=number.getText().toString();

Send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ReceiveAsyncTask().execute("http://192.168.1.4:80/Service1.svc");
}
});
}
public class Message implements KvmSerializable {
public String Fname,Lname,Age;

public Message(){}
public Message(String F_name,String S_namae,String Age_stirng){
Fname=F_name;
Lname=S_namae;
Age=Age_stirng;
}
public Object getProperty(int index){
switch (index){
case 0:
return Fname;
case 1:
return Lname;
case 2:
return Age;
}
return null;
}

@Override
public int getPropertyCount() {
return 3;
}

@Override
public void setProperty(int index, Object value) {
switch (index){
case 0:
Fname=value.toString();
break;
case 1:
Lname=value.toString();
break;
case 2:
Age=value.toString();
break;
default:
break;
}
}

@Override
public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info) {
switch (index){
case 0:
info.type=PropertyInfo.STRING_CLASS;
info.name="Fname";
break;
case 1:
info.type=PropertyInfo.STRING_CLASS;
info.name="Lname";
break;
case 2:
info.type=PropertyInfo.STRING_CLASS;
info.name="Age";
break;
default:
break;
}
}

}

Anonymous said...

public class ReceiveAsyncTask extends AsyncTask
{

@Override
protected String doInBackground(String... params)

{
final String METHOD_NAME = "TestwithArgum";
final String NAMESPACE = "http://tempuri.org/";
final String SOAP_ACTION = "http://tempuri.org/IService1/TestwithArgum";

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
Message db=new Message();
db.Fname="Akil";
db.Lname="Akil";
db.Age="Five";


PropertyInfo pi=new PropertyInfo();
pi.setName("db");
pi.setValue(db);
pi.setType(db.getClass());
request.addProperty(pi);

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);

envelope.addMapping(NAMESPACE,"Message",new Message().getClass());
HttpTransportSE androidHttpTransport = new HttpTransportSE(params[0]);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result1 =(SoapObject) envelope.getResponse();
resulData = result1.toString();
}
catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return resulData;
}

@Override
protected void onPostExecute(String finalresult) {
super.onPostExecute(finalresult);
revtxt.setText(finalresult);
}
}
}

------------------------------
On a short note to say,my service in getting 3 string as a input and return a String as Output.....
By android studio using Ksoap 3.5.2 , i have to send 3 String as input and get a string as output...

s1,s2,s3 are three input data i need to pass,
How to do it?

I have also tried,
Message db=new Message();
db.Fname="sdfd"
db.Lname="sdfd"
db.Age="sdfd"

---------------------------

Error Message i'm getting is

Soap fault - fault code:'aDeserialization Failed' fault string

--------------------------------
I have a doubt

what is the use of

public Message(){}
public Message(String F_name,String S_namae,String Age_stirng){
Fname=F_name;
Lname=S_namae;
Age=Age_stirng;
}


System intelligence tells that, Message constructor(3 argument) is been not used
-------------------------------
Please help me on this

Anonymous said...

On a short note to say,my service in getting 3 string as a input and return a String as Output.....
By android studio using Ksoap 3.5.2 , i have to send 3 String as input and get a string as output...
s1,s2,s3 are three input data i need to pass,
How to do it?

I have also tried,
Message db=new Message();
db.Fname="sdfd"
db.Lname="sdfd"
db.Age="sdfd"
Error Message i'm getting is
Soap fault - fault code:'aDeserialization Failed' fault string
--------------------------------
I have a doubt
what is the use of
public Message(){}
public Message(String F_name,String S_namae,String Age_stirng){
Fname=F_name;
Lname=S_namae;
Age=Age_stirng;
}
System intelligence tells that, Message constructor(3 argument) is been not used
-------------------------------
Please help me on this

Anonymous said...

Hi, I'm Arulmani from UAE,
Last 4 post has been posted by me.....

wcf(.svc) service is Getting 3 string as input and return String as ouput,

when i search how to pass a class as parameter, i got this link. it was very useful , by implementing KVMSerialize we define class and its property,value count, etc....

how pass input to it ?

Please review my post and help me ...........

Accurate Solutions said...

Web-Design Deutschland und Web Development -Unternehmen in Deutschland E-Commerce- Website -Entwicklung, Web-Site -Design , Flash- Website usw. besuchen Sie uns @ http://www.accuratesolutionsltd.com/e-commerce-entwicklung/

niaziakmal khan said...

Programming is combination of intelligent and creative work. Programmers can do anything with code. The entire Programming tutorials that you mention here on this blog are awesome. Beginners Heap also provides latest tutorials of Programming from beginning to advance level.
Be with us to learn programming in new and creative way.

seravina danniella said...

Your blog has given me that thing which I never expect to get from all over the websites. Nice post guys!

regards,
melbourne web designer

Anonymous said...

Hi, I have a web service that I have made using Java. Hosted this web service on Amazon AWS EB.

This web service implements a string method with no arguments.

When I am trying to access the web service using my android app I am getting anyType{}.

Please help.

«Oldest ‹Older   201 – 334 of 334   Newer› Newest»

Post a Comment