当前位置: 首页 > 面试题库 >

Ksoap:将用户定义的类作为参数传递给Web方法时,无法序列化异常

王凯旋
2023-03-14
问题内容

我花了几天的时间试图弄清楚如何使用户定义的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;
        }
    }

这就是我在活动中使用kso​​ap调用服务的方式:

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服务方法。我将不胜感激任何帮助 。


问题答案:

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

这是CallSoapKvmSerializable为此定义的用于发送对象的类:

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;

}


 类似资料:
  • 我正在编写一个方法,如果我想将一个类传递给一个方法,其中代码的一部分包括检查对象是否属于某种类型。这就是我想要的(但显然不行): 关于如何做到这一点有什么提示吗?谢谢!

  • 我有一个用例,其中一个类存在于一个包的两个版本中。 到目前为止还不错(我相信)。 然后我有一个使用该类的应用程序,为了避免为不同的包版本重写应用程序,我想传递应该使用的类(即感兴趣的包)作为应用程序的参数。所以像这样的东西 我相信我可以把这个叫做如果我在构造函数中传递的实例,那么我会通过实例对象调用静态方法,不是吗? 另一方面,在上面的示例中,是一个类对象,因此我不能像上面那样调用静态方法。 这是

  • 在下面的代码中,我希望将'races.class'作为参数传递给方法'get allraces()'。我该怎么做?

  • 我有静态方法在我的类 这就是定义 这里用的是 这是我得到的一个错误 E0167类型为“void(TV_DepthCamAgent::)(int count,int copied_file)”的参数与类型为“void()(int,int)”的参数不兼容 错误C3867“TV_DepthCamAgent::progress_callback”:非标准语法;使用' 我做错了什么?

  • 问题内容: 当我定义一个自定义类型时,基础类型的类型似乎对我是否可以按原样将其传递给函数还是需要对其进行转换有所不同。 问题是: 为什么和起作用,但不起作用? https://play.golang.org/p/buKNkrg5y- 在这里,当我运行此函数时,它会抱怨,尽管它是基础类型。但是当我打电话或他们成功运行时。 问题答案: 和 您的新类型是2种不同的不同类型。在预期的地方,您必须传递typ

  • 问题内容: 我很好奇Go中是否有可能。我有多种方法的类型。是否可以有一个函数,该函数需要一个方法参数,然后将其称为类型? 这是我想要的一个小例子: Go认为type 有一个称为的方法,而不是用传入的方法名称替换它。 问题答案: 是的,有可能。您有2(3)个选项: 规范:方法表达式 该表达式产生的功能与第一个参数等效,但具有一个显式接收器。它有签名。 在这里,方法接收器是显式的。您只需将方法名称(具