2013-10-27 2 views
2

Я провел несколько дней, пытаясь понять, как я могу сделать свой пользовательский класс java сериализуемым, чтобы я мог отправить его как параметр в android ksoap вызов веб-метода C#. Ниже мой код и исключения, брошенные в logcat при вызове webservice, я был бы признателен, если бы получил немедленный ответ или помощь.Ksoap: исключение Serialize Can not при передаче определяемого пользователем класса в качестве параметра для веб-метода

Мой 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 в качестве параметра для метода веб-службы. Буду признателен за любую помощь.

ответ

3

Я отредактировал свой пример и добавлю вам новый и полный пример, который, я думаю, может вам помочь. В этом примере у меня есть таблица клиентов в базе данных на стороне сервера, и я хочу вставить данные из android в эту таблицу через KvmSerializable определяемый пользователем класс. Вот 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; 
    } 

} 

} 

А теперь с # пользовательского класса для клиентов:

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; 

} 
+0

Ваша точка является сделать такой же порядок свойств (имя, тупит, OppPhoneNum) в C# и класс java? , но, по крайней мере, он должен пройти процесс сериализации, а затем после этого будет обнаружен переключатель данных. так как они все одного типа String –

+0

Я протестировал этот путь, и я могу отправить массив объектов из этого пользовательского класса. Какова ваша общая цель использования этого? это отправить массив объектов? –

+0

Да, я пытаюсь отправить список объектов XY. Спасибо за ваши усилия, я попробую и дам вам знать, работает ли это для меня. –

0

Я считаю, что правильный пример является неполным. Вы должны что-то сделать с объектом «soapDetail» (класс CallSoap), добавив его в объект «soapDetails» или что-то в этом роде, потому что если я не отправил пустой массив.

EDITED:

Эта строка кода отсутствует на итератора, чтобы завершить Маджид Daei НЕДЖАД пример:

soapDetails.addSoapObject(soapDetail[i]); 
+0

Пожалуйста, добавьте недостающую строку кода в качестве комментария к ответу Маджида. :) – Barett

+0

Первый абзац следует добавить в качестве комментария к исходному вопросу. Таким образом, это не отдельный ответ. – Barett

Смежные вопросы