3

我花了几天时间试图弄清楚如何使我的用户定义的 java 类可序列化,以便我可以将它作为 android ksoap 调用中的参数发送到 c# web 方法。下面是我的代码和调用 web 服务时 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();
        }
    }**

日志猫异常:

java.lang.RuntimeException: Cannot Serialize: [XY .....** 

注意:我正在尝试将 XY 对象列表作为参数传递给 Web 服务方法。我将不胜感激任何帮助 。

4

2 回答 2

3

我已经编辑了我的示例并为您添加了新的完整示例,我认为它可以帮助您。在这个例子中,我在服务器端数据库中有一个客户表,我想通过 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;

}
于 2013-10-27T18:05:18.507 回答
0

我认为验证为正确的例子是不完整的。您必须对对象“soapDetail”(CallSoap 类)执行某些操作,将其添加到对象“soapDetails”或其他内容中,因为如果我没有发送空数组。

编辑:

迭代器缺少这行代码来完成 Majid Daei Nejad 示例:

soapDetails.addSoapObject(soapDetail[i]);
于 2016-01-27T16:38:34.077 回答