I'm trying to pass an object to web service using ksopa2 library. I'm trying something like this:
RangeInfo controllingArea = new RangeInfo();
controllingArea.setLow(txtControllingAreaSearch.getText().toString());
PropertyInfo propertyControllingArea = new PropertyInfo();
propertyControllingArea.setType(new RangeInfo().getClass());
propertyControllingArea.setName("IControllingarea");
propertyControllingArea.setValue(controllingArea);
request.addProperty(propertyControllingArea);
PropertyInfo maxNoOfHits = new PropertyInfo();
maxNoOfHits.setValue(txtMaxNoHitsSearch.getText().toString());
maxNoOfHits.setName("IMaxnoofhits");
maxNoOfHits.setType(PropertyInfo.INTEGER_CLASS);
request.addProperty(maxNoOfHits);
My RangeInfo class is like this:
public String sign = "I";
public String option = "EQ";
public String low;
public String high;
public RangeInfo(){}
public RangeInfo(SoapObject soapObject)
{
if (soapObject == null)
return;
if (soapObject.hasProperty("Sign"))
{
Object obj = soapObject.getProperty("Sign");
if (obj != null && obj.getClass().equals(SoapPrimitive.class)){
SoapPrimitive j =(SoapPrimitive) obj;
sign = j.toString();
}else if (obj!= null && obj instanceof String){
sign = (String) obj;
}
}
if (soapObject.hasProperty("Option"))
{
Object obj = soapObject.getProperty("Option");
if (obj != null && obj.getClass().equals(SoapPrimitive.class)){
SoapPrimitive j =(SoapPrimitive) obj;
option = j.toString();
}else if (obj!= null && obj instanceof String){
option = (String) obj;
}
}
if (soapObject.hasProperty("Low"))
{
Object obj = soapObject.getProperty("Low");
if (obj != null && obj.getClass().equals(SoapPrimitive.class)){
SoapPrimitive j =(SoapPrimitive) obj;
low = j.toString();
}else if (obj!= null && obj instanceof String){
low = (String) obj;
}
}
if (soapObject.hasProperty("High"))
{
Object obj = soapObject.getProperty("High");
if (obj != null && obj.getClass().equals(SoapPrimitive.class)){
SoapPrimitive j =(SoapPrimitive) obj;
high = j.toString();
}else if (obj!= null && obj instanceof String){
high = (String) obj;
}
}
}
#Override
public Object getProperty(int arg0) {
switch(arg0){
case 0:
return sign;
case 1:
return option;
case 2:
return low;
case 3:
return high;
}
return null;
}
#Override
public int getPropertyCount() {
return 4;
}
#Override
public void getPropertyInfo(int index, #SuppressWarnings("rawtypes") Hashtable arg1, PropertyInfo info) {
switch(index){
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Sign";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Option";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Low";
break;
case 3:
info.type = PropertyInfo.STRING_CLASS;
info.name = "High";
break;
}
}
#Override
public void setProperty(int arg0, Object arg1) {
}
public void setSign(String sign) {
this.sign = sign;
}
public void setOption(String option) {
this.option = option;
}
public void setLow(String low) {
this.low = low;
}
public void setHigh(String high) {
this.high = high;
}
In the server side I'm getting value of "IMaxnoofhits" variable, but "IControllingarea" is always null!!!
Someone has passed or imagine what could be the problem?
Thanks!
It looks to me like when you instantiate your RangeInfo controllingArea = new RangeInfo(); class you're not passing in a SoapObject so you're just calling the empty constructor, instead of the second constructor which has all your code.
Also, I know this isn't a part of your question but your maxNoOfHits parameter is set to the Integer class, even though .setValue looks like you're passing in a String.
Thanks guys,
I solved it by my self. Here is what i did. And it is working to send complex object to the request.
RangeInfo controllingArea = new RangeInfo();
controllingArea.setLow("Value");
controllingArea.setHigh("Value");
PropertyInfo item = new PropertyInfo();
item.setType(controllingArea.getClass());
item.setName("item");
item.setValue(controllingArea);
SoapObject object1 = new SoapObject("","IControllingarea");
object1.addProperty(item);
request.addSoapObject(object1);
PropertyInfo maxNoOfHits = new PropertyInfo();
maxNoOfHits.setValue(txtMaxNoHitsSearch.getText().toString());
maxNoOfHits.setName("IMaxnoofhits");
maxNoOfHits.setType(PropertyInfo.INTEGER_CLASS);
request.addProperty(maxNoOfHits);
Best regards.
Related
I'm struggeling on getting a complex type (list) out of my response for three days now, but always getting a ClassCastException
D/SOAPEnvelope(1552): Error: java.lang.ClassCastException: org.ksoap2.serialization.SoapObject cannot be cast to com.example.webservice.ResponsiblepartyGetResponse
I read several linked pages / tutorials so often that I almost can tell them by mind, including these four very helpful pages:
http://seesharpgears.blogspot.de/2010/10/web-service-that-returns-array-of.html
http://code.google.com/p/ksoap2-android/wiki/CodingTipsAndTricks#sending/receiving_array_of_complex_types_or_primitives
ksoap2 Receive Array of complex objects via SOAP
How to parse this Web service response in Android?
and many more, but I still don't get it :(
I hope I'll give you all the input you need to show me my mistake and give me a hint to fix it. The webservice is already successfully implemented in a rich client application and I have to build an android app now using the same webservice.
My first step is to handle a "responsibleparty_get"-Response.
My response looks (with a limit to 3, but can be more/less) like this. Note: There are two additional properties of the "responsiblePartyFacades" that are just null for these responses (see below in the JAVADOC).
responsibleparty_getResponse{
responsiblePartyFacades=anyType{
id=1;
name=hans;
discriminator=person;
admin=false;
};
responsiblePartyFacades=anyType{
id=2;
name=dieter;
discriminator=person;
admin=false;
};
responsiblePartyFacades=anyType{
id=3;
name=stefan;
discriminator=person;
admin=false;
};
}
The related XML looks like this (got out of SoapUI):
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:responsibleparty_getResponse xmlns:ns2="http://ws.my-url.com/">
<responsiblePartyFacades>
<id>1</id>
<name>hans</name>
<discriminator>person</discriminator>
<admin>false</admin>
</responsiblePartyFacades>
<responsiblePartyFacades>
<id>2</id>
<name>dieter</name>
<discriminator>person</discriminator>
<admin>false</admin>
</responsiblePartyFacades>
<responsiblePartyFacades>
<id>3</id>
<name>stefan</name>
<discriminator>person</discriminator>
<admin>false</admin>
</responsiblePartyFacades>
</ns2:responsibleparty_getResponse>
</S:Body>
</S:Envelope>
From our JAVADOC (out of the rich client) the responsiblePartyFacades looks the same:
* <complexType name="responsiblePartyFacade">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="discriminator" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="admin" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
* <element name="children" type="{http://ws.my-url.com/}pairIntBoolFacade" maxOccurs="unbounded" minOccurs="0"/>
* <element name="plantcomponents" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
So far, so nice.
I wrote these classes to handle the reponse:
ResponsiblepartyGetResponse
public class ResponsiblepartyGetResponse extends Vector<ResponsiblePartyFacade> implements KvmSerializable {
private static final long serialVersionUID = -8065084038519643055L;
#Override
public Object getProperty(int index) {
return this.get(index);
}
#Override
public int getPropertyCount() {
return this.size();
}
#Override
public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info) {
info.name = "ResponsiblePartyFacades";
info.type = new ResponsiblePartyFacade().getClass();
}
#Override
public void setProperty(int index, Object value) {
// add ResponsiblePartyFacade to vector
this.add((ResponsiblePartyFacade) value);
}
}
ResponsiblePartyFacade: For now i comment out the vecor-items as they are not in the response, because I throught it might work (as there are several blogs on the web saying ksoap2 vector does not work).
public final class ResponsiblePartyFacade implements KvmSerializable {
private Integer id;
private String name;
private String discriminator;
private Boolean admin;
// private List<PairIntBoolFacade> children; // not used
// private List<Integer> plantcomponents; // not used
public ResponsiblePartyFacade() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDiscriminator() {
return discriminator;
}
public void setDiscriminator(String discriminator) {
this.discriminator = discriminator;
}
public Boolean getAdmin() {
return admin;
}
public void setAdmin(Boolean admin) {
this.admin = admin;
}
/*
public List<PairIntBoolFacade> getChildren() {
if (children == null) {
children = new ArrayList<PairIntBoolFacade>();
}
return children;
}
public void setChildren(List<PairIntBoolFacade> children) {
this.children = children;
}
public List<Integer> getPlantcomponents() {
if (plantcomponents == null) {
plantcomponents = new ArrayList<Integer>();
}
return plantcomponents;
}
public void setPlantcomponents(List<Integer> plantcomponents) {
this.plantcomponents = plantcomponents;
}
*/
public int getPropertyCount() {
return 4;
}
public Object getProperty(int __index) {
switch(__index) {
case 0: return id;
case 1: return name;
case 2: return discriminator;
case 3: return admin;
//case 4: return children;
//case 5: return plantcomponents;
}
return null;
}
public void setProperty(int __index, Object value) {
switch(__index) {
case 0: id = Integer.parseInt(value.toString()); break;
case 1: name = value.toString(); break;
case 2: discriminator = value.toString(); break;
case 3: admin = Boolean.parseBoolean(value.toString()); break;
//case 4: children = (List) __obj; break;
//case 5: plantcomponents = (List) __obj; break;
}
}
public void getPropertyInfo(int __index, Hashtable __table, PropertyInfo __info) {
switch(__index) {
case 0:
__info.name = "id";
__info.type = Integer.class; break;
case 1:
__info.name = "name";
__info.type = String.class; break;
case 2:
__info.name = "discriminator";
__info.type = String.class; break;
case 3:
__info.name = "admin";
__info.type = Boolean.class; break;
/*
case 4:
__info.name = "children";
__info.type = PropertyInfo.VECTOR_CLASS;
case 5:
__info.name = "plantcomponents";
__info.type = PropertyInfo.VECTOR_CLASS;
*/
}
}
}
Here is my webservice call:
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// For testing I only want to have 3 results
request.addProperty("limit", "3");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
// add mapping
// ResponsiblepartyGetResponse got namespace in XML
envelope.addMapping(NAMESPACE, "ResponsiblepartyGetResponse", new ResponsiblepartyGetResponse().getClass());
// ResponsiblePartyFacades doesn't have namespace. I also tried to add namespace, but same result
envelope.addMapping("", "ResponsiblePartyFacades", new ResponsiblePartyFacade().getClass());
ResponsiblepartyGetResponse result = new ResponsiblepartyGetResponse();
try {
AuthTransportSE androidHttpTransport = new AuthTransportSE(URL, USERNAME, PASSWORD);
androidHttpTransport.debug = true;
androidHttpTransport.call(SOAP_ACTION, envelope);
// this shows me my result as a string, see above
System.out.println(envelope.bodyIn.toString());
// Trying to case the response -> Exception
result = (ResponsiblepartyGetResponse) envelope.bodyIn;
} catch (Exception e){
Log.d("SOAPEnvelope", "Error: "+e.toString());
}
return result;
As in some tutorials shown I also tried to parse the response manually. But for this the response has to be casted to "SoapObject" like this
SoapObject response = (SoapObject)envelope.getResponse();
When I do this I get the following exception:
05-11 07:09:56.389: D/SOAPEnvelope(2209): Error: java.lang.ClassCastException: java.util.Vector cannot be cast to org.ksoap2.serialization.SoapObject
05-11 07:09:56.402: D/SOAPEnvelope(2209): java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
Can anybody give me a hint?
After despairing one more day I found a soultion that goes back to "misco" in java.lang.ClassCastException: org.ksoap2.serialization.SoapObject
I don't try to cast the Response anymore, but building the List myself by hand:
androidHttpTransport.call(SOAP_ACTION, envelope);
ArrayList<ResponsiblePartyFacades> returnlist = new ArrayList<ResponsiblePartyFacades>();
java.util.Vector<SoapObject> rs = (java.util.Vector<SoapObject>) envelope.getResponse();
if (rs != null)
{
for (SoapObject cs : rs)
{
ResponsiblePartyFacades rp = new ResponsiblePartyFacades();
rp.setId(Integer.parseInt(cs.getProperty(0).toString()));
rp.setName(cs.getProperty(1).toString());
rp.setDiscriminator(cs.getProperty(2).toString());
rp.setAdmin(Boolean.parseBoolean(cs.getProperty(3).toString()));
Log.d("WS", "ID = "+rp.getId() +" name = "+rp.getName()+" disc = "+rp.getDiscriminator()+" admin = "+rp.getAdmin().toString() );
returnlist.add(rp);
}
}
here is my solution. It works for me. Instead of using Vector, get the value of SoapObject response.
SoapObject response = (SoapObject) envelope.getResponse();
int count = response.getPropertyCount();
Log.i("count", Integer.toString(count));
for (int i = 0; i < count; i++) {
int id = Integer.parseInt(response
.getPropertyAsString("id"));
Log.i("id", Integer.toString(id));
String name = (response.getPropertyAsString("name"));
Log.i("name", name);
String discriminator = (response
.getPropertyAsString("discriminator"));
Log.i("discriminator", discriminator);
//add this value to List
}
public ArrayList<CadernetaTO> buscarTodasAsCadernetas() {
ArrayList<CadernetaTO> lista = new ArrayList<CadernetaTO>();
SoapObject buscarTodasAsCadernetas = new SoapObject(NAMESPACE, BUSCAR_TODOS);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(buscarTodasAsCadernetas);
envelope.implicitTypes = true;
HttpTransportSE http = new HttpTransportSE(URL);
try {
http.call(URL + "/" + BUSCAR_TODOS,envelope);
Vector<SoapObject> resposta = (Vector<SoapObject>) envelope.getResponse();
Log.i("entrou no Vector", "Vector");
for (SoapObject soapObject : resposta) {
Log.i("entrou no for", "msg");
CadernetaTO cadern = new CadernetaTO();
Log.i("entrou no to", "CadernetaTO");
cadern.setIdCaderneta(Integer.parseInt(soapObject.getProperty("idCaderneta").toString()));
Log.i("ggigfjjg", "passou linha 1");
cadern.setDose(soapObject.getProperty("dose").toString());
Log.i("ggigfjjg", "passou linha 2");
cadern.setLote(soapObject.getProperty("lote").toString());
Log.i("ggigfjjg", "passou linha 3");
cadern.setData_aplicacao(soapObject.getProperty("data_aplicacao").toString());
Log.i("ggigfjjg", "passou linha 4");
cadern.setSituacao(soapObject.getProperty("situacao").toString());
Log.i("ggigfjjg", "passou linha 5");
cadern.setFkCrianca_idCrianca(Integer.parseInt(soapObject.getProperty("fkCrianca_idCrianca").toString()));
Log.i("ggigfjjg", "passou linha 6");
cadern.setFkVacina_idVacina(Integer.parseInt(soapObject.getProperty("fkVacina_idVacina").toString()));
Log.i("ggigfjjg", "passou linha 7");
lista.add(cadern);
Log.i("testando", cadern.getSituacao() + cadern.getDose() + cadern.getIdCaderneta());
//http.getServiceConnection().setRequestProperty("Connection", "close");
System.setProperty("http.keepAlive", "false");
}
So, I am a newbie in mobile development and interoperability. I am developing a Android application that comunnicates send a Contact object to a remove server that is running a .NET Web Service (via kSOAP). But there is a 500 error in the server and I really don't know how to map it because it is running remotely and my host plan doesn't allow me to debug remotely. I believe it is an error in the interpretation of the Java object in the ASP.NET Web Service, I don't know if it is necessary to deserialize the object and how to do it. I hope that a more experienced developer could help me. I already used primitive objects (string, int and others) and it worked like a charm but I really prefer to work with my models.
The Android Application - Call of the Web Service:
public int webServiceMethodRegisterUser(String... paramss)
{
String resultData;
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
Contact c = new Contact(paramss[0], paramss[1]);
c._email = paramss[0];
c._password = paramss[1];
c._cellphonesim = paramss[2];
c._simoperator = paramss[3];
PropertyInfo pi = new PropertyInfo();
pi.setName("contact");
pi.setValue(c);
pi.setType(c.getClass());
request.addProperty(pi);
//request.addProperty("useremail", paramss[0]);
//request.addProperty("userpass", paramss[1]);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, "Contact" , new Contact().getClass());
//Marshal floatMarshal = new Marshal();
//floatMarshal.register(envelope);
//Marshal oi = new ();
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
Object result=(Object)envelope.getResponse();
//To get the data.
resultData= result.toString();
publishProgress(resultData);
return Integer.parseInt(resultData);
} catch (Exception e) {
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
throw new RuntimeException(e1.toString());
}
throw new RuntimeException(e.toString());
}
}
Custom Object in Java
package com.example.ivi;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.MarshalDate;
import org.ksoap2.serialization.PropertyInfo;
public class Contact implements KvmSerializable {
// private variables
int _id;
String _email;
String _password;
String _simoperator;
String _cellphonesim;
String _sn_facebook;
String _sn_linkedin;
String _sn_googleplus;
String _sn_orkut;
String _sn_twitter;
Date _last_refresh;
Date _register_date;
public Contact(int id, String email, String password, String simoperator,
String cellphonesim, String facebook, String linkedin,
String googleplus, String orkut, String twitter, Date refreshuser,
Date userregister) {
_id = id;
_email = email;
_password = password;
_simoperator = simoperator;
_cellphonesim = cellphonesim;
_sn_facebook = facebook;
_sn_linkedin = linkedin;
_sn_googleplus = googleplus;
_sn_orkut = orkut;
_sn_twitter = twitter;
_last_refresh = refreshuser;
_register_date = userregister;
}
public Contact() {
}
// constructor
public Contact(int id, String email, String password) {
this._id = id;
this._email = email;
this._password = password;
}
// constructor
public Contact(String email, String password) {
this._email = email;
this._password = password;
}
#Override
public Object getProperty(int arg0) {
switch (arg0) {
case 0:
return _id;
case 1:
return _email;
case 2:
return _password;
case 3:
return _simoperator;
case 4:
return _cellphonesim;
case 5:
return _sn_facebook;
case 6:
return _sn_linkedin;
case 7:
return _sn_googleplus;
case 8:
return _sn_orkut;
case 9:
return _sn_twitter;
case 10:
return _last_refresh;
case 11:
return _register_date;
}
return null;
}
#Override
public int getPropertyCount() {
// TODO Auto-generated method stub
return 12;
}
#Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
switch (index) {
case 0:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "UserId";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserEmail";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserPassword";
break;
case 3:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserSimOperator";
break;
case 4:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserCellPhoneSim";
break;
case 5:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserFacebook";
break;
case 6:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserLinkedin";
break;
case 7:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserGoogleplus";
break;
case 8:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserOrkut";
break;
case 9:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserTwitter";
break;
case 10:
info.type = MarshalDate.DATE_CLASS;
;
info.name = "UserLastRefresh";
break;
case 11:
info.type = MarshalDate.DATE_CLASS;
;
info.name = "UserRegisterDate";
break;
}
}
#Override
public void setProperty(int index, Object value) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
switch (index) {
case 0:
_id = Integer.parseInt(value.toString());
break;
case 1:
_email = value.toString();
break;
case 2:
_password = value.toString();
break;
case 3:
_simoperator = value.toString();
break;
case 4:
_cellphonesim = value.toString();
break;
case 5:
_sn_facebook = value.toString();
break;
case 6:
_sn_linkedin = value.toString();
break;
case 7:
_sn_googleplus = value.toString();
break;
case 8:
_sn_orkut = value.toString();
break;
case 9:
_sn_twitter = value.toString();
break;
case 10:
try {
_last_refresh = formatter.parse(value.toString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case 11:
try {
_register_date = formatter.parse(value.toString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
. NET Web Service
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
namespace WebServiceIvi
{
[WebService(Namespace = "http://www.ividomain.somee.com/Service1")]
[WebServiceBinding(ConformsTo = WsiProfiles.None)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public int registerUser(Contact contato)
{
string connString = CONNECTION_STRING;
SqlConnection con = new SqlConnection(connString);
SqlCommand cmdSQL = con.CreateCommand();
try
{
con.Open();
cmdSQL.CommandText = String.Format("INSERT INTO [databaseivi].[dbo].[UsersIvi] ([Useremail],[Userpass],[Userxml],[Usersince]) VALUES('{0}','{1}',null ,getDate())", contato.UserEmail, contato.UserPassword);
int result = cmdSQL.ExecuteNonQuery();
con.Close();
return result;
}
catch (SqlException e)
{
foreach (SqlError error in e.Errors)
{
return error.Number;
}
return 0;
}
}
}
}
The Custom Object in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WebServiceIvi
{
public class Contact
{
public Contact(int id, String email, String password, String simoperator, String cellphonesim, String facebook, String linkedin, String googleplus, String orkut, String twitter, DateTime refreshuser, DateTime userregister )
{
_id = id;
_email = email;
_password = password;
_simoperator = simoperator;
_cellphonesim = cellphonesim;
_sn_facebook = facebook;
_sn_linkedin = linkedin;
_sn_googleplus = googleplus;
_sn_orkut = orkut;
_sn_twitter = twitter;
_last_refresh = refreshuser;
_register_date = userregister;
}
public Contact()
{
}
int _id;
String _email;
String _password;
String _simoperator;
String _cellphonesim;
String _sn_facebook;
String _sn_linkedin;
String _sn_googleplus;
String _sn_orkut;
String _sn_twitter;
DateTime _last_refresh;
DateTime _register_date;
public int UserId
{
set { _id = value; }
get
{
if (_id <= 0) return _id;
else return 0;
}
}
public string UserEmail
{
set { _email = value; }
get
{
if (_email != null) return _email.ToString();
else return string.Empty;
}
}
public string UserPassword
{
set { _password = value; }
get
{
if (_password != null) return _password.ToString();
else return string.Empty;
}
}
public string UserSimOperator
{
set { _simoperator = value; }
get
{
if (_simoperator != null) return _simoperator.ToString();
else return string.Empty;
}
}
public string UserCellPhoneSim
{
set { _cellphonesim = value; }
get
{
if (_cellphonesim != null) return _cellphonesim.ToString();
else return string.Empty;
}
}
public string UserFacebook
{
set { _sn_facebook = value; }
get
{
if (_sn_facebook != null) return _sn_facebook.ToString();
else return string.Empty;
}
}
public string UserLinkedin
{
set { _sn_linkedin = value; }
get
{
if (_sn_linkedin != null) return _sn_linkedin.ToString();
else return string.Empty;
}
}
public string UserGoogleplus
{
set { _sn_googleplus = value; }
get
{
if (_sn_googleplus != null) return _sn_googleplus.ToString();
else return string.Empty;
}
}
public string UserOrkut
{
set { _sn_orkut = value; }
get
{
if (_sn_orkut != null) return _sn_orkut.ToString();
else return string.Empty;
}
}
public string UserTwitter
{
set { _sn_twitter = value; }
get
{
if (_sn_twitter != null) return _sn_twitter.ToString();
else return string.Empty;
}
}
public DateTime UserLastRefresh
{
set { _last_refresh = value; }
get
{
if (_last_refresh != null) return DateTime.Parse(_last_refresh.ToString());
else return DateTime.MinValue;
}
}
public DateTime UserRegisterDate
{
set { _register_date = value; }
get
{
if (_register_date != null) return DateTime.Parse(_register_date.ToString());
else return DateTime.MinValue;
}
}
}
}
The SOAP Request XML:
POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.ividomain.somee.com/Service1/registerUser"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<registerUser xmlns="http://www.ividomain.somee.com/Service1">
<contato>
<UserId>int</UserId>
<UserEmail>string</UserEmail>
<UserPassword>string</UserPassword>
<UserSimOperator>string</UserSimOperator>
<UserCellPhoneSim>string</UserCellPhoneSim>
<UserFacebook>string</UserFacebook>
<UserLinkedin>string</UserLinkedin>
<UserGoogleplus>string</UserGoogleplus>
<UserOrkut>string</UserOrkut>
<UserTwitter>string</UserTwitter>
<UserLastRefresh>dateTime</UserLastRefresh>
<UserRegisterDate>dateTime</UserRegisterDate>
</contato>
</registerUser>
</soap:Body>
</soap:Envelope>
I've been stuck in this for a while and didn't found any implementation and deserialization of a java model in .NET. I hope someone out there helps me! =D
ThiagoMello, I had this error days ago and solve it generting java class from this site:
http://www.wsdl2code.com/Pages/Home.aspx
With this classes my code works fine! Try it.
Hope this helps.
Joan.
I try to create web service, code for webservice client of android appliaction as below:
String SOAP_ACTION = "";
String METHOD_NAME = "operation1";
String NAMESPACE = "http://service.livebackup.com/";
String URL = "http://192.168.1.3:8084/test/webService?wsdl";
Button signin;
Thread t;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
signin = (Button) findViewById(R.id.btn_sign_in);
signin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showDialog(0);
t=new Thread() {
public void run() {
tryLogin();
}
};
t.start();
}
});
}
private void tryLogin() {
// TODO Auto-generated method stub
EditText etxt_user = (EditText) findViewById(R.id.txt_username);
EditText etxt_pass = (EditText) findViewById(R.id.txt_password);
String username = etxt_user.getText().toString();
String password = etxt_pass.getText().toString();
callWebService(username,password);
}
private void callWebService(String username, String password) {
// TODO Auto-generated method stub
//String result = "ishan";
try {
int no=2;
SoapObject request = new SoapObject(NAMESPACE,METHOD_NAME);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
PropertyInfo p1 = new PropertyInfo();
Check C = new Check();//use check KvmSerializable{
C.UserName=username;
C.PassWord=password;
p1.setName("C");
p1.setValue(C);
p1.setType(C.getClass());
request.addProperty(p1);
SoapSerializationEnvelope envelope =new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=false;
envelope.setOutputSoapObject(request);
androidHttpTransport.call(SOAP_ACTION, envelope);
Log.v("Ok","wait for response");
Object results =(Object)envelope.getResponse();
Log.v("Ok","Connection has response object" +results);
Log.v("Ok","jj");
//to get the data String resultData=result.getProperty(0).toString();
String temp = results.toString();
Log.v("Ok","Connection has response" +temp);
}
catch (Exception e) {
// TODO: handle exception
System.out.println("Error:" +e.getClass().getName()+":"+e.getMessage());
}
}
check class as follow:
public class Check implements KvmSerializable{
public String UserName;
public String PassWord;
public Check(){}
public Check(String userName, String passWord) {
super();
UserName = userName;
PassWord = passWord;
}
#Override
public Object getProperty(int arg0) {
// TODO Auto-generated method stub
switch(arg0)
{
case 0:
return UserName;
case 1:
return PassWord;
}
return null;
}
#Override
public int getPropertyCount() {
// TODO Auto-generated method stub
return 2;
}
#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 = "UserName";
break;
case 1:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "PassWord";
break;
default:break;
}
}
#Override
public void setProperty(int index, Object value) {
// TODO Auto-generated method stub
switch(index)
{
case 0:
UserName = value.toString();
break;
case 1:
PassWord = value.toString();
break;
default:
break;
}
}
}
My problem: i use net beans jax-ws on server side,
how to i handle a request of username & password from android ws -client,
i complete done with only request.addproperty("userName",username);
plz,help..
First of all, in your client:
UserName and PassWord are Strings, but you treated them as int. In Check class do this:
#Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
switch(index) {
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "UserName";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "PassWord";
break;
default:
break;
}
Remove wsdl at the end of your URL string:
String URL = "http://192.168.1.3:8084/test/webService/";
In your server: check it out http://www.ibm.com/developerworks/webservices/library/ws-android/index.html
Hope it helps.
I am having a Web Client in Android using ksoap2 but I can't pass the string array as a parameter to the webservice.
Here's my code
String[] items={"hello","world"};
request.addproperty("str",items);
First use "soapUI" to see correct request structure(like item names,item namespaces , ...).
We assume that you want to write like this XML in request:(here n0 and n1 are namespaces)
<n0:strarray xmlns:n0="http://n0 ..." xmlns:n1="http://n1 ...">
<n1:string>hello</n1:string>
<n1:string>world</n1:string>
</n0:strarray>
extend a class from vector:
import java.util.Hashtable;
import java.util.Vector;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class StringArraySerializer extends Vector<String> implements KvmSerializable {
//n1 stores item namespaces:
String n1 = "http://n1 ...";
#Override
public Object getProperty(int arg0) {
return this.get(arg0);
}
#Override
public int getPropertyCount() {
return this.size();
}
#Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
arg2.setName = "string";
arg2.type = PropertyInfo.STRING_CLASS;
arg2.setNamespace = n1;
}
#Override
public void setProperty(int arg0, Object arg1) {
this.add(arg1.toString());
}
}
To build the request you have to do this:
1-make a new Vector-Object from this class:
StringArraySerializer stringArray = new StringArraySerializer();
2-then you can add elements:
stringArray.add("hello");
stringArray.add("world");
3-then you create a PropertyInfo with it:
//n0 stores array namespace:
String n0 = "http://n0 ...";
stringArrayProperty = new PropertyInfo();
stringArrayProperty.setName("strarray");
stringArrayProperty.setValue(stringArray);
stringArrayProperty.setType(stringArray.getClass());
stringArrayProperty.setNamespace(n0);
4-then you add all the properties to the request:
Request = new SoapObject(NAMESPACE, METHOD_NAME);
Request.addProperty(stringArrayProperty);
Reference:
ksoap2-android,CodingTipsAndTricks
it is like that you shold add it one by one.
public class ExtendedSoapObject extends SoapObject
{
public ExtendedSoapObject(String namespace, String name)
{
super(namespace, name);
}
public ExtendedSoapObject(SoapObject o)
{
super(o.getNamespace(), o.getName());
for (int i = 0; i < o.getAttributeCount(); i++)
{
AttributeInfo ai = new AttributeInfo();
o.getAttributeInfo(i, ai);
ai.setValue(o.getAttribute(i));
addAttribute(ai);
}
for (int i = 0; i < o.getPropertyCount(); i++)
{
PropertyInfo pi = new PropertyInfo();
o.getPropertyInfo(i, pi);
pi.setValue(o.getProperty(i));
addProperty(pi);
}
}
#Override
public SoapObject addProperty(String name, Object value)
{
if (value instanceof Object[])
{
Object[] subValues = (Object[]) value;
for (int i = 0; i < subValues.length; i++)
{
super.addProperty(name, subValues[i]);
}
}
else
{
super.addProperty(name, value);
}
return this;
}
#Override
public Object getProperty(String name)
{
List<Object> result = new ArrayList<Object>();
for (int i = 0; i < properties.size(); i++)
{
PropertyInfo prop = (PropertyInfo) properties.elementAt(i);
if (prop.getName() != null && prop.getName().equals(name))
{
result.add(unwrap(prop));
}
}
if (result.size() == 1)
{
return result.get(0);
}
else if (result.size() > 1)
{
return result.toArray(new Object[0]);
}
else
{
return null;
}
}
public Object[] getArrayProperty(String name)
{
Object o = getProperty(name);
Object values[] = null;
if (o != null)
{
if (o instanceof Object[])
{
values = (Object[]) o;
}
else
{
values = new Object[1];
values[0] = o;
}
}
return values;
}
Object unwrap(Object o)
{
if (o instanceof PropertyInfo)
{
return unwrap(((PropertyInfo) o).getValue());
}
else if (o instanceof SoapPrimitive || o instanceof SoapObject)
{
return o;
}
return null;
}
}
I am getting a "casting" error on a property of complex object that is sent to a .NET web service using KSOAP2 from an Android device. The property is an array of complex objects. The documentation on the internet has helped me send and receive simple data types (strings, ints, dates, etc). I can even read an array of complex objects from a .NET web service. I just cannot send back an array of complex objects to the web service. Please help. Here is what I have:
Environment:
Client = Android Development using the latest KSOAP lib for communication.
Server = .NET Web Service (Visual Studio 2008). Note: this is NOT WCF.
.NET Web Service:
[SoapRpcMethod(), WebMethod]
public void WriteCaseInfo(CaseInformation caseInfo)
{
...
...
}
ANDROID CLIENT CODE:
Parent Class Sent as Complex Parameter:
public class CaseInformation extends IABaseKSoap2Serializable
{
public String Name;
public int Id;
public Vector<MultiPartDataElement> SiteListItems = new Vector<MultiPartDataElement>();
#Override
public Object getProperty(int arg0)
{
switch(arg0)
{
case 0:
return Name;
case 1:
return Id;
case 2:
return SiteListItems;
}
return null;
}
#Override
public int getPropertyCount()
{
return 3;
}
#Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info)
{
switch(index)
{
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Name";
break;
case 1:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "Id";
break;
case 2:
info.type = new Vector<MultiPartDataElement>().getClass();
info.name = "SiteListItems";
break;
default:break;
}
}
#Override
public void setProperty(int index, Object value)
{
switch(index)
{
case 0:
Name = value.toString();
break;
case 1:
Id = Integer.parseInt(value.toString());
break;
case 2:
SiteListItems = (Vector<MultiPartDataElement>)value;
break;
default:
break;
}
}
}
Note: If I remove the SiteListItems property from the client code and the web service, everything works.
Complex Class used in Array within the above object:
public class MultiPartDataElement extends IABaseKSoap2Serializable
{
public int Id;
public String Name;
// default constructor
public MultiPartDataElement()
{
}
// overloaded constructor
public MultiPartDataElement(int id, String name)
{
Id = id;
Name = name;
}
#Override
public Object getProperty(int arg0)
{
switch(arg0)
{
case 0:
return Id;
case 1:
return Name;
}
return null;
}
#Override
public int getPropertyCount()
{
return 2;
}
#Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info)
{
switch(index)
{
case 0:
info.type = PropertyInfo.INTEGER_CLASS;
info.name = "Id";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Name";
break;
default:break;
}
}
#Override
public void setProperty(int index, Object value)
{
switch(index)
{
case 0:
Id = Integer.parseInt(value.toString());
break;
case 1:
Name = value.toString();
break;
default:
break;
}
}
}
Code to Send object as a Parameter to the .Net Web Service:
public static boolean WriteCaseInfo()
{
boolean status = false;
CaseInformation caseInfo = new CaseInformation();
caseInfo.Id = 2725;
caseInfo.Name = "Craig M. Buck";
caseInfo.SiteListItems = new Vector<MultiPartDataElement>();
caseInfo.SiteListItems.add(new MultiPartDataElement(1, "CMB1"));
caseInfo.SiteListItems.add(new MultiPartDataElement(2, "CMB2"));
String methodName = "WriteCaseInfo";
SoapObject request = new SoapObject(NAMESPACE, methodName);
request.addProperty("caseInfo", caseInfo);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
envelope.dotNet = false;
envelope.encodingStyle = SoapSerializationEnvelope.XSD;
envelope.addMapping(IABaseKSoap2Serializable.NAMESPACE, "MultiPartDataElement", new MultiPartDataElement().getClass());
envelope.addMapping(IABaseKSoap2Serializable.NAMESPACE, "CaseInformation", new CaseInformation().getClass());
HttpTransportSE transport = new HttpTransportSE(WebAPIURL + CaseServicesURL);
transport.debug = true;
transport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
try
{
List<HeaderProperty> headers = BuildHeader();
transport.call(NAMESPACE + methodName, envelope, headers);
String requestDump = transport.requestDump;
String soapDump = transport.responseDump;
SoapObject response = (SoapObject) envelope.bodyIn;
if(response != null)
status = new Boolean(response.getProperty(0).toString());
}
catch(Exception e)
{
status = false;
}
return status;
}
Request Dump from KSOAP:
<?xml version="1.0" encoding="utf-8"?><v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"><v:Header /><v:Body><n0:WriteCaseInfo id="o0" c:root="1" xmlns:n0="http://www.medical.draeger.com/webservices/"><caseInfo i:type="n1:CaseInformation" xmlns:n1="http://www.medical.draeger.com/webservices/encodedTypes"><Name i:type="d:string">Craig M. Buck</Name><Id i:type="d:int">2725</Id><SiteListItems i:type="c:Array" c:arrayType="d:anyType[2]"><item i:type="n1:MultiPartDataElement"><Id i:type="d:int">1</Id><Name i:type="d:string">CMB1</Name></item><item i:type="n1:MultiPartDataElement"><Id i:type="d:int">2</Id><Name i:type="d:string">CMB2</Name></item></SiteListItems></caseInfo></n0:WriteCaseInfo></v:Body></v:Envelope>
Note: What I think the issue is, is that the array is defined as "anyTyp" and not MultiPartDataElement -> ... the question is what am I doing wrong here??
Response Dump from KSOAP (After Call):
SoapException: Server was unable to read request. ---> System.InvalidOperationException: There is an error in XML document (1, 828). ---> System.InvalidCastException: Cannot assign object of type System.Object[] to an object of type Draeger.IT.Platform.Web.WebServices.MultiPartDataElement[]
I've had similar problem. You might want to try my personal solution.
http://www.codeproject.com/Tips/222578/Android-access-to-NET-Web-Service-with-object-as-p
You could do this:
int propertyCount = countryDetails.getPropertyCount();
ArrayList list = new ArrayList(propertyCount);
lv_arr = new String[propertyCount];
for (int i = 0; i < propertyCount; i++) {
Object property = countryDetails.getProperty(i);
if (property instanceof SoapObject) {
SoapObject countryObj = (SoapObject) property;
String countryName = countryObj.getProperty("countryName").toString();
list.add(countryName);
}
}
from : Parsing ksoap2 response