我花了几天时间试图找出如何使我的用户定义的java类可序列化,以便我可以将它作为参数发送到android ksoap调用c#web方法。 下面是我的代码和调用webservice时在logcat中抛出的异常,如果我得到即时答复或帮助,我将感激不尽。
我的java课程XY.java
:
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class XY implements KvmSerializable {
public static Class XY_CLASS = XY.class;
private String MyNum;
private String OppPhoneNum;
private String Name;
public XY()
{
}
public XY(String MyNum, String Name, String oppNum)
{
this.MyNum = MyNum;
this.Name = Name;
this.OppPhoneNum = oppNum;
}
public String getPhoneNum() {
return MyNum;
}
public void setPhoneNum(String MyNum) {
this.MyNum = MyNum;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getOpponentPhoneNum() {
return OppPhoneNum;
}
public void setOpponentPhoneNum(String OppPhoneNum) {
this.OppPhoneNum = OppPhoneNum;
}
@Override
public Object getProperty(int arg0) {
switch(arg0)
{
case 0:
return MyNum;
case 1:
return OppPhoneNum;
case 2:
return Name;
}
return null;
}
@Override
public int getPropertyCount() {
// TODO Auto-generated method stub
return 3;
}
@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
switch(index)
{
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "MyNum";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "OppPhoneNum";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Name";
break;
default:break;
}
}
@Override
public void setProperty(int index, Object value) {
switch(index)
{
case 0:
MyNum = value.toString();
break;
case 1:
OppPhoneNum = value.toString();
break;
case 2:
Name = value.toString();
break;
default:
break;
}
}
}
C#等效类:
[Serializable]
public class XY
{
public System.String Name
{
get;
set;
}
public System.String MyNum
{
get;
set;
}
public System.String OppPhoneNum
{
get;
set;
}
}
这就是我在我的活动中使用ksoap调用服务的方式:
private void unKnown(List<XY> entries)
{
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo entriesProp =new PropertyInfo();
entriesProp.setName("entries");
entriesProp.setValue(entries);
entriesProp.setType(ArrayList.class);
//Use this to add parameters
request.addProperty(entriesProp);
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, "XY", XY.XY_CLASS);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ADDCONTACTS, envelope);
// Get the SoapResult from the envelope body.
if (envelope.bodyIn instanceof SoapFault)
{
String str= ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
}
else
{
SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
if(resultsRequestSOAP != null)
{
Log.i("AddContacts", "Adding Contacts succeeded");
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}**
Logcat异常:
java.lang.RuntimeException: Cannot Serialize: [XY .....**
注意:我正在尝试将XY对象列表作为参数传递给Web服务方法。 我将不胜感激任何帮助。
答案 0 :(得分:3)
我已编辑了我的示例并为您添加了新的完整示例,我认为它可以帮助您。在这个例子中,我在服务器端数据库中有一个customer表,我想通过KvmSerializable用户定义的类将android中的数据插入到该表中。
以下是客户的KvmSerializable
用户定义类:
public class Customer implements KvmSerializable {
public int Customer_ID;
public String Customer_Name;
public String Customer_Family;
public Customer() {
}
public Customer(int customer_id,
String customer_name,
String customer_family) {
Customer_ID = customer_id;
Customer_Name = customer_name;
Customer_Family = customer_family;
}
public Object getProperty(int arg0) {
// TODO Auto-generated method stub
switch (arg0) {
case 0:
return Customer_ID;
case 1:
return Customer_Name;
case 2:
return Customer_Family;
}
return null;
}
public int getPropertyCount() {
// TODO Auto-generated method stub
return 25;
}
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 = "Customer_ID";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Customer_Name";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "Customer_Family";
break;
default:
break;
}
}
public void setProperty(int index, Object value) {
// TODO Auto-generated method stub
switch (index) {
case 0:
Customer_ID = Integer.parseInt(value.toString());
break;
case 1:
Customer_Name = value.toString();
break;
case 2:
Customer_Family = value.toString();
break;
default:
break;
}
}
}
现在c#用户定义的客户类:
public class Customer
{
public int Customer_ID;
public string Customer_Name;
public string Customer_Family;
}
以下是我为发送CallSoap
对象定义的KvmSerializable
类:
public class CallSoap {
public static String NAMESPACE = "http://127.0.0.1:80/";
public static String URL = "http://127.0.0.1:80/service.asmx?WSDL";
public static Customer[] customers;
public static int AddCustomer(Customer[] customers) {
String MethodName = "AddCustomer";
SoapObject soapAddCustomer = new SoapObject(NAMESPACE, MethodName);
//customers Parameter
SoapObject soapDetails = new SoapObject(NAMESPACE, "customers");
SoapObject soapDetail[] = new SoapObject[customers.length];
for (int i=0;i<customers.length;i++){
soapDetail[i]= new SoapObject(NAMESPACE, "Customer");
soapDetail[i].addProperty("Customer_ID", customers[i].Customer_ID);
soapDetail[i].addProperty("Customer_Name", customers[i].Customer_Name);
soapDetail[i].addProperty("Customer_Family", customers[i].Customer_Family);
}
soapAddRequest.addSoapObject(soapDetails);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(soapAddRequest);
envelope.addMapping(NAMESPACE, "Customer", new Customer().getClass());
HttpTransportSE HttpTransportSE = new HttpTransportSE(URL);
try {
HttpTransportSE.call(NAMESPACE + MethodName, envelope);
String result = envelope.getResponse().toString();
return Integer.parseInt(result);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
最后是服务器端的AddCustomer
方法:
[WebMethod]
public int AddCustomer(Customer[] customers)
{
for(int i=0;i<customers.Length;i++){
//Access to customer fields for allrows via
int id = customers[i].Customer_ID;
String name = customers[i].Customer_Name;
String = customers[i].Customer_Family;
}
return customers.Length;
}
答案 1 :(得分:0)
我认为验证是正确的例子是不完整的。您必须对对象'soapDetail'(CallSoap类)执行某些操作,将其添加到对象'soapDetails'或其他内容,因为如果我没有发送空数组。
编辑:
迭代器上缺少这行代码来完成Majid Daei Nejad示例:
soapDetails.addSoapObject(soapDetail[i]);