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



As you can see, the code here is so trivial that I am honestly surprised why it does not come out of the box like it does for ints.
The next example shows how to Marhsal Dates with KSOAP:

package Marshals;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.kobjects.isodate.IsoDate;
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 Dates - crucial to serialization for SOAP
 */
public class MarshalDate implements Marshal
{

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


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


        public void writeInstance(XmlSerializer writer, Object obj) throws IOException {
             writer.text(IsoDate.dateToString((Date) obj, IsoDate.DATE_TIME));
            }
    
}

As you probably assume, in order to tell KSOAP how to use the marshaling, you need to use the register() method in the following manner:

String MethodName = "GetEventById";
SoapObject request = GetSoapObject(MethodName);
AddProperty(request, Event);
SoapSerializationEnvelope envelope = GetEnvelope(request);
        
envelope.addMapping(NAMESPACE, "Event",Event.getClass());

MarshalDate md = new MarshalDate();
md.register(envelope);
       
SoapObject response =  MakeCall(URL,envelope,NAMESPACE,MethodName);

Basically that is all you need to get started with KSOAP marshaling.

56 comments:

Gerard said...

Hi. Could you please paste the source code of the Event class? Thanks

SeeSharpWriter said...

Sure ... here it is:

public class Event implements KvmSerializable {

public int EventId;
public String Name;
public String Description;
public Date Date;
public User Publisher;
public Location Location;
public boolean IsActive;
public String Image;
public Category Category;


public Event() {
Publisher = new User();
Location = new Location();
Date = new Date();
Image = "http://image_url";
Category = new Category();
}

public Event(String name, String description, Date eventDate, String image,
Location location, Category category) {

this.Name = name;
this.Description = description;
this.Date = eventDate;
this.Image = image;
this.Location = location;
this.Category = category;
}

@Override
public Object getProperty(int index) {
switch(index)
{
case 0:
return EventId;
case 1:
return Name;
case 2:
return Description;
case 3:
return Date;
case 4:
return Publisher.Email;
case 5:
return Location.LocationId;
case 6:
return IsActive;
case 7:
return Image;
case 8:
return Category.CategoryId;
case 9:
return Location.CoordinateX;
case 10:
return Location.CoordinateY;
}
return null;
}

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

@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
// TODO Auto-generated method stub
switch(index)
{
case 0:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "EventId";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Name";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Description";
break;
case 3:
info.type = Date.getClass();
info.name = "Date";
break;
case 4:
info.type = PropertyInfo.STRING_CLASS;
info.name = "PublisherId";
break;
case 5:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "LocationId";
break;
case 6:
info.type = PropertyInfo.BOOLEAN_CLASS;
info.name = "IsActive";
break;
case 7:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Image";
case 8:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "CategoryId";
break;
case 9:
info.type = Double.class;
info.name = "CoordinateX";
break;
case 10:
info.type = Double.class;
info.name = "CoordinateY";
break;
default:break;
}

}

@Override
public void setProperty(int index, Object value) {
switch(index)
{
case 0:
EventId = Integer.parseInt(value.toString());
break;
case 1:
Name = value.toString();
break;
case 2:
Description = value.toString();
case 3:
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm");
try {
Date = (Date)df.parse(value.toString().replace("T", " "));
} catch (ParseException e) {
e.printStackTrace();
}
break;
case 4:
Publisher.Email = value.toString();
break;
case 5:
Location.LocationId = Integer.parseInt(value.toString());
break;
case 6:
IsActive = Boolean.parseBoolean(value.toString());
break;
case 7:
Image = value.toString();
case 8:
Category.CategoryId = Integer.parseInt(value.toString());
break;
case 9:
Location.CoordinateX = Double.parseDouble(value.toString());
break;
case 10:
Location.CoordinateY = Double.parseDouble(value.toString());
break;
}
}

}

Anonymous said...

Hi,

Can you provide a sample for ComplexData type. My websevice takes around 10 parameters (all boolean). Then there is extension, which also takes some 10 parameters.
Do i need to Marshal those?

Regards,
Nk

SeeSharpWriter said...

Hi, Nk.
Basically you don't need to marshal boolean types. Is your ComplexData encapsulated within another complex data type, or it's just a class with 10 boolean parameters?

Valter said...

Hello
I am having difficulty sending a date like property to the webservice. Could you post an example of how to do? Thanks

SeeSharpWriter said...

Hi Valter, you might try the following code:

public class MarshalDate implements Marshal { public static Class DATE_CLASS = new Date().getClass();

public Object readInstance(XmlPullParser parser, String namespace, String name, PropertyInfo expected)
throws IOException, XmlPullParserException
{
//IsoDate.DATE_TIME=3
String Test1 = parser.nextText();
return IsoDate.stringToDate(parser.nextText(), IsoDate.DATE_TIME);


}
public void register(SoapSerializationEnvelope cm)
{
cm.addMapping(cm.xsd, "dateTime", MarshalDate.DATE_CLASS, this);
// "DateTime" is wrong use "dateTime" ok

}
public void writeInstance(XmlSerializer writer, Object obj)
throws IOException
{
String Test="";
Test = IsoDate.dateToString((Date) obj, IsoDate.DATE_TIME);
writer.text(IsoDate.dateToString((Date) obj, IsoDate.DATE_TIME));
}

SeeSharpWriter said...

PropertyInfo pi = new PropertyInfo();
pi.name= "Date"; // name of the parameter in your dotnet variable
pi.type = MarshalDate.DATE_CLASS;
// add property with your value, I use new Date(System.currentTimeMillis()
rpc3.addProperty(pi, new Date(System.currentTimeMillis()));
SoapSerializationEnvelope envelope3 = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope3.bodyOut = rpc3; envelope3.dotNet = false;
MarshalDate md = new MarshalDate();
md.register(envelope3);
envelope3.setOutputSoapObject(rpc3);

Craig said...

Great article! Using the information that you posted, really helped me with KSOAP2. Unfortunately, I am stuck on one thing - enum. A web service returns a class with a property that is an enumeration defined in the web service. KSOAP2 throws an error because it doesn't know how to handle it. Any ideas on what to do? I tried to marshal it, no go. I am think serialization like your previous article, but what should the value actually be stored as? Do you have a code snipet with an enum being supported?

Thanks in advance,

Craig

Naresh said...

Hi, please can you post only the entire double value code

SeeSharpWriter said...

Naresh, the rest of the functions are located in the other few posts for Android, but I will copy them here as well then, too. Thanks for notifying me about that.

Dan said...

Hey there , just wanted to suggest the simplest solution. When adding property to the request , in the SOAP envelope, you could just add the String value of the long number and it works great, because the soap message does not know what type it reveives
Here is what worked for me :
request.addProperty("arg0",String.valueOf(doubleNumber));
request.addProperty("arg1",String.valueOf(doubleNumber));

Hope this helps for simplified requests :D

SeeSharpWriter said...

Dan, yes it easiest to send strings in simple scenarios - but usually in real-life situations we have complex classes with dozens of properties and developers want to work with the same abstraction on both the server and the client device.

C H said...

Hi - I'm trying to call my web service method that takes 4 parameters. 3 of them are of type Guid (for which marshalling Java's UUID works), and the last is a custom type: LocationLibrary.Location. This type is in a separate DLL (LocationLibrary) that I load into the WCF web service project and it is basically comprised of two doubles, latitude and longitude.

This parameter name in the method definition is "loc". In my Android project, I've created a class named "Location" that is similar to the .NET version. I've also created a simple Marshal class for this, which basically just uses the fromString and toString methods. Finally, I register the envelope with the marshal instance for Location. However, I get this error and cannot seem to get it to work. Can you point me in the right direction? Thanks!

Error:

07-30 00:42:08.186: WARN/System.err(8723): 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/:loc. The InnerException message was 'Error in line 1 position 522. Element 'http://tempuri.org/:loc' contains data from a type that maps to the name 'http://www.w3.org/2001/XMLSchema:Location'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'Location' 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: org.kxml2.kdom.Node@4053aa28

SeeSharpWriter said...

Have you tried moving the class in the same DLL ?

Unknown said...

Hmm, I got it to work by moving the Location class into the same DLL, but that will make it difficult to manage since there are already clients out there using the service. Any idea how to get it to work without that? Thanks!

Spoon said...

Hi,

I am trying to send dateTime argument to a .net webservice and i am not successful. I implemented the method above but still get an error message.
"SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.' faultactor: 'null' detail: org.kxml2.kdom.Node@2b0eb5a0" Can somebody advise what i am doing wrong?

Here is a sample:
public DrawResult GetDrawResult (Date d) throws Exception
{
String SOAP_ACTION = "http://website.co.za/methodname";
String METHOD_NAME = "methodname";

SoapObject so = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(so);

PropertyInfo pi = new PropertyInfo();
pi.setName("drawDate");
pi.type = MarshalDate.class;
pi.setValue(d);
so.addProperty(pi);

MarshalDate md = new MarshalDate();
md.register(envelope);

HttpTransportSE androidHttpTransport = new HttpTransportSE (URL);
androidHttpTransport.debug = true;
androidHttpTransport.call(SOAP_ACTION, envelope);

SoapObject response = (SoapObject)envelope.getResponse();


return null;
}

Spoon said...

Hi,

I am having an issue regarding Marshaling of date argument to a .net webservice method.

requestdump:2011-08-25T22:00:00.000Z

Error Message: SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.' faultactor: 'null' detail: org.kxml2.kdom.Node@2b067fb8

please help, i have been at this for days now.
Thanks!

SeeSharpWriter said...

Spoon, check the date format on your server side - perhaps SQL server treats the day as the month

Spoon said...

SeeSharpWriter, i am trying to paste a the request dump between a Request generated by VS 2010 and by KSoap2. The issue is really not the format, its as if the dateTime is ignored when it gets the Server side. How can i paste the requestDump?

Anonymous said...

Hi

Please, could you give me a hint about how to serialize a type XMLGregorianCalendar, is it possible i m a bit confused now about how to do it i followed your examples but it still shows me an exception about the serialization :(


Thanks

SeeSharpWriter said...

I really do not know how to serialize XML Gregorian Calendar type. If anyone else knows, please share

Ramesh Yankati said...

Hi

In one scenario I have to send soap request to the web service.The web service expects the Complex object as a input.I tried sending the soap request But all the time I am getting XMLpullparser Exception saying Expected start_tag.
My custom object implemts the KvmSerializable.My code some thing likeSoapObject soapRquest=new SoapObject(NAMESPACE,METHOD_NAME);
PropertyInfo orderProperty=new PropertyInfo();
RetrieveOrderRequest retrieveOrderRequest = new RetrieveOrderRequest();
retrieveOrderRequest.setOrderNumber("H0620064094-1");
orderProperty.setName("RetrieveOrderRequest");
orderProperty.setType(retrieveOrderRequest.getClass());
orderProperty.setValue(retrieveOrderRequest);
soapRquest.addProperty(orderProperty);
MarshalRetrieveOrderRequest mar=new MarshalRetrieveOrderRequest();
SoapSerializationEnvelope envelope=GetEnvelope(soapRquest);
mar.register(envelope);
HttpTransportSE httpRequest = new HttpTransportSE(URL);
httpRequest.debug=true;
try{
httpRequest.call(SOAP_ACTION,envelope);
soapResponse=(SoapObject)envelope.getResponse();
LoginStatus.setText(soapResponse.toString());
}
catch (XmlPullParserException e) {
Log.d(TAG,"XmlPullParserException "+e.getMessage());
LoginStatus.setText("Error "+e.getMessage());
}
catch (IOException e) {
Log.d(TAG,"IOException"+e.getMessage());
LoginStatus.setText("Error "+e.getMessage());
}

I am always getting the XMLpull parser exception.Kindly help me ..

SeeSharpWriter said...

Can you post the RetrieveOrderRequest class as well? Does it contain only primitive data type attributes?

Anonymous said...

Hi, I'm trying to send a group of data from a DB to my android app,,, What I need to implement this. 'Cause takes a lot of time to get the data in order one by one.


Could you post an example about what is needed and how to interpret the types?

SeeSharpWriter said...

What kind of data are you sending back to Android? Usually you can return an array of objects with KSOAP 2, or even if you want you can return an XML string which you could parse on mobile device's side.
Please consider this article if you want to learn how to return an array of custom objects from your .NET web service:
http://seesharpgears.blogspot.com/2010/10/web-service-that-returns-array-of.html

Anonymous said...

I'm sending back to android Integer and String types, it's like a query on that you returns an Id, name, classification data (for example). So, should I return an array of objects? or is neccesary use marshall.



Dav.

SeeSharpWriter said...

I think you should create a custom class and return a single object with all those attributes.

Anonymous said...

Thanks, I'll try that.



Dav.

Anonymous said...

Hi, is it possible to marshal and ArrayList of custom Java object?

SeeSharpWriter said...

I have never succeeded to send it from Android to the server, but it definitely works for returning an array as a result from your web service. Please note that the array must not be wrapped inside a custom object, for example you cannot do the following:

public class Car {

public Door[] doors;

}

and then try to write a web service like this:

[WebMethod]
public int CountCarsWith4Doors(Car[] cars){ //... }

Anonymous said...

Hello all i am developing an BB app and wants to send complex parameters . Here is my ksoap call code

String serviceUrl = cd.getUrl();
SoapObject rpc = new SoapObject(serviceNamespace, "getTradeOrderTotal");


SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
MarshalDouble md = new MarshalDouble();
md.register(envelope);

envelope.dotNet = false;
envelope.setOutputSoapObject(rpc);
envelope.encodingStyle = SoapSerializationEnvelope.XSD;



envelope.addMapping(serviceNamespace, "MTradeOrder", new MTradeOrder().getClass());


MTradeOrder mt = new MTradeOrder(); //This is my complex class implementing kvmserializable.


mt.portfolioName=AppScreen.name2;
mt.securityName=AppScreen.symbol11; // These are the parameters that i am setting to my complex class
mt.orderType=AppScreen.ordertype;
mt.priceType=AppScreen.Pricetype;
mt.quantityRequested=AppScreen.quantity1;
mt.orderTermName=ActiveTradeOrder.orderterm;
mt.limitPrice=AppScreen.limitprice;



PropertyInfo pi = new PropertyInfo();
pi.type=MarshalDouble.class;


rpc.addProperty("arg0", mt);




HttpTransportBasicAuth ht = new HttpTransportBasicAuth(serviceUrl, AppScreen.wsunS, AppScreen.wspwdS);
ht.debug = true;

String result;
try
{

ht.call(soapAction, envelope);

result = (envelope.getResponse()).toString();

System.out.println("Request::::::dump::::::::::::::::::::::::::::: \n" + ht.requestDump);

System.out.println("Response>>>>>>>>>>>>>>>>> \n" + ht.responseDump);


UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
Dialog.alert("Login Successful!");
}
});

}
catch (Exception ex)
{
result = ex.toString();
System.out.println("Exception: " + result);
System.out.println("Request::::::::::::::::::::::::::::::::::: \n" + ht.requestDump);
System.out.println("Response>>>>>>>in exceptionnnn>>>>>>>>>> \n" + ht.responseDump);
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
Dialog.alert("Login Unsuccessful!\nPlease try again.");
}
});
}

}

But i am getting this exception:-

Exception: SoapFault - faultcode: 'S:Server' faultstring: 'javax.xml.bind.UnmarshalException
- with linked exception:
[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,471]
Message: Element type "systemGenerated" must be followed by either attribute specifications, ">" or "/>".]' faultactor: 'null' detail: org.kxml2.kdom.Node@bc82f019


can anybody help me in this .My complex class is implemneting kvmserializable and also made marshling class for passing double parameters.Please help me !!

Amar said...

Hello all i am developing an BB app and wants to send complex parameters . Here is my ksoap call code

String serviceUrl = cd.getUrl();
SoapObject rpc = new SoapObject(serviceNamespace, "getTradeOrderTotal");


SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
MarshalDouble md = new MarshalDouble();
md.register(envelope);

envelope.dotNet = false;
envelope.setOutputSoapObject(rpc);
envelope.encodingStyle = SoapSerializationEnvelope.XSD;



envelope.addMapping(serviceNamespace, "MTradeOrder", new MTradeOrder().getClass());


MTradeOrder mt = new MTradeOrder(); //This is my complex class implementing kvmserializable.


mt.portfolioName=AppScreen.name2;
mt.securityName=AppScreen.symbol11; // These are the parameters that i am setting to my complex class
mt.orderType=AppScreen.ordertype;
mt.priceType=AppScreen.Pricetype;
mt.quantityRequested=AppScreen.quantity1;
mt.orderTermName=ActiveTradeOrder.orderterm;
mt.limitPrice=AppScreen.limitprice;



PropertyInfo pi = new PropertyInfo();
pi.type=MarshalDouble.class;


rpc.addProperty("arg0", mt);




HttpTransportBasicAuth ht = new HttpTransportBasicAuth(serviceUrl, AppScreen.wsunS, AppScreen.wspwdS);
ht.debug = true;

String result;
try
{

ht.call(soapAction, envelope);

result = (envelope.getResponse()).toString();

System.out.println("Request::::::dump::::::::::::::::::::::::::::: \n" + ht.requestDump);

System.out.println("Response>>>>>>>>>>>>>>>>> \n" + ht.responseDump);


UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
Dialog.alert("Login Successful!");
}
});

}
catch (Exception ex)
{
result = ex.toString();
System.out.println("Exception: " + result);
System.out.println("Request::::::::::::::::::::::::::::::::::: \n" + ht.requestDump);
System.out.println("Response>>>>>>>in exceptionnnn>>>>>>>>>> \n" + ht.responseDump);
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
Dialog.alert("Login Unsuccessful!\nPlease try again.");
}
});
}

}

But i am getting this exception:-

Exception: SoapFault - faultcode: 'S:Server' faultstring: 'javax.xml.bind.UnmarshalException
- with linked exception:
[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,471]
Message: Element type "systemGenerated" must be followed by either attribute specifications, ">" or "/>".]' faultactor: 'null' detail: org.kxml2.kdom.Node@bc82f019



can anybody help me in this .My complex class is implemneting kvmserializable and also made marshling class for passing double parameters.Please help me !!

Amar said...
This comment has been removed by the author.
Amar said...

Anybody has a solution to this??

SeeSharpWriter said...

I think this might be erroneous

pi.type=MarshalDouble.class;


rpc.addProperty("arg0", mt);

the property should be of type MTradeOrder, not MarshalDouble

Amar said...

Thanks for your kind reply SeeSharp.As told by you i have made some changes :

mt.portfolioName="00000000";
mt.securityName="ACCESS"; //
mt.orderType="BUY";
mt.priceType="LIMIT";

mt.quantityRequested=22; // double values
mt.orderTermName="00000001";
mt.limitPrice=33; // double values

PropertyInfo pi = new PropertyInfo();
pi.type=MTradeOrder.class;


rpc.addProperty("arg0", pi.type);// also try this thing rpc.addProperty("arg0", pi);

But getting this as output:-

Exception: java.lang.RuntimeException: Cannot serialize: class com.emx.forex.complex.MTradeOrder
Request:::::::::::::::::::::::::::::::::::
null
Response>>>>>>>in exceptionnnn>>>>>>>>>>
null

Along with it i am aslo attaching my wsdl acceptance parameters



Please help me in find the solution of it.Struggling with this for long while.
Thanks.

Amar said...

Please provide me a solution seaSharp its only you who can provide me a help for it.I am eagerly waiting .
Thanks

SeeSharpWriter said...

Maybe there is an attribute in your class that cannot be serialized by default. Try removing attributes from the class one by one and see if it gets serialized properly.

Amar said...

I have try this thing .The point i noticed is that XML format generated by the ksoap is not accurate.See my earlier post in which request is generated.What should i do now.Provide me any idea.

Anonymous said...

Hello, if you have a class as:
Class User implements KMSoapSerializable{
String name;
Direction address;
}

Class Direction implements KmSoapSerializable {
String name;
int latitude;
int longitude;
}

and you pass as argument a User, I have the error Could not convert null to bean field 'latitud', type int in the server side with Axis deserialize

SeeSharpWriter said...

That is because your class encapsulates another class, but you provide no means on how to (de)serialize it.

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

Hassan Mehmood said...

I have implemented KvmSerializable interface on my class "CustomImage". which holds byte[]. (bytes of an image actually size around 10KB)

my web service method requires bytes[] as an argument.

When i try to pass bytes[] from android, the KSOAP2 gives exception:

"java.lang.RuntimeException: Cannot serialize: [B@46e9f008"


i checked by not passing any argument to the service, it give me exception:

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

Please let me know if you want to have a look at the source code too. Its a test project any way..

Thanks alot.

Hassan Mehmood said...

the requestDump remain null too as it can't serialize it somehow.

"java.lang.RuntimeException: Cannot serialize: [B@46e9f008"

gaurav said...

please provide me answer of my problem
I want to parse and deparse class with KvmSerializable.
Class describe below.

public class AcceptInvitationRequest{
private Invitation invitation = null;
private String sessionId;
private String guId;

}

Here Invitation is class reference variable
which is describe below.

public class Invitation{
private String emailAddress = null;
private String greeting = null;
private String invitationGuid = null;
private String invitationImage = null;
private String message = null;
private String relationshipGuid = null;
private String sentByUser = null;
private String toName = null;

}

please tell me answer. thanks in advance.

Rathu said...

HI,
I just want to insert the data to the webservice while clicking the add button. The problem arises when i try to parse the complex data types like date,float etc.. So i decided to use kvmserializable. whether it is correct or not...

lanquansan said...

thanks for share

Anonymous said...

Hi, please can you post only the entire double value code. Thank you!

Richard Joseph said...
This comment has been removed by the author.
Radhika said...

how to send byte[] and an integer to the wcf service my method in the service is like this
Validate(int index, byte[] data)

and iam able to call the wcf either passing both int values or both byte[] values.
i tried like this

PropertyInfo pi = new PropertyInfo();
pi.setName("index");
pi.setValue(index);
pi.setType(PropertyInfo.INTEGER_CLASS);
request.addProperty(pi);
pi = new PropertyInfo();
pi.setName("data");
pi.setValue(data); pi.setType(MarshalBase64.BYTE_ARRAY_CLASS);
request.addProperty(pi);
marshal = new MarshalBase64();
marshal.register(envelope);


but iam getting an error server cannot parse the data

SeeSharpWriter said...

Radhika, how about sending it as String ? I think it will simplify things.

Gani said...

Very nice tutorial easily understandable. I have one requirement that My asmx web service takes a json object as a parameter. For that I have used the Gson class to convert it to Json. but when I used that code it throws me a "Invocation Target Exception" at the following line of code

String json;
Gson gson = new Gson();
json=gson.toJson(thisitm);

Anhsirk Dasarp said...

Great tutorial. Could you please tell me how to do it for Java.util.set. Set's are not working with KSOAP. And instead Vector is. But problem with vector is that only 1st element of it gets serialized. Could you pl guide me how to serialize Set?

Anonymous said...

Felicidades Vladimir, es lo que estaba buscando.

Gracias.

Anonymous said...

I find it interesting, that MarshallDouble works fine on all numbers, but when performing the actuall call, double values of 0.0 cause java lang runtime exception 'Cannot serialize: 0.0'

Is there a solution to that?

Anonymous said...

Can you tell how to send UUID type to the wcfService Please?How to Marshal UUID Class

Post a Comment