KSOAP2处理复杂响应(矢量)

时间:2013-05-11 07:22:51

标签: android vector response ksoap2

我现在正忙着从我的回复中获取一个复杂类型(列表)三天,但总是得到一个ClassCastException

D/SOAPEnvelope(1552): Error: java.lang.ClassCastException: org.ksoap2.serialization.SoapObject cannot be cast to com.example.webservice.ResponsiblepartyGetResponse

我经常阅读几个链接页面/教程,我几乎可以用心思告诉他们,包括这四个非常有用的页面:

还有更多,但我仍然没有得到它:(

我希望我能给你所有的输入,告诉我我的错误,并给我一个解决方法。 web服务已经在富客户端应用程序中成功实现,我现在必须使用相同的Web服务构建一个Android应用程序。

我的第一步是处理“responsparty_get” - 响应。

我的回复看起来(限制为3,但可以更多/更少)像这样。注意:“responsiblePartyFacades”还有两个属性,这些属性对于这些响应都是空的(请参阅下面的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;
   };

}

相关的XML看起来像这样(离开了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>

从我们的JAVADOC(富客户端)中,responsiblePartyFacades看起来是一样的:

 * &lt;complexType name="responsiblePartyFacade">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="id" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
 *         &lt;element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="discriminator" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="admin" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
 *         &lt;element name="children" type="{http://ws.my-url.com/}pairIntBoolFacade" maxOccurs="unbounded" minOccurs="0"/>
 *         &lt;element name="plantcomponents" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>

到目前为止,非常好。

我写了这些类来处理响应:

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:现在我评论了vecor-items,因为它们不在响应中,因为我可能会工作(因为网上有几个博客说ksoap2矢量不起作用)。

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;
            */
        }
    }

}

这是我的网络服务电话:

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;

正如在一些教程中所示,我也尝试手动解析响应。但为此,响应必须像“

”一样转换为“SoapObject”
SoapObject response = (SoapObject)envelope.getResponse();

当我这样做时,我得到以下异常:

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

有人可以给我一个提示吗?

3 个答案:

答案 0 :(得分:3)

在绝望一天之后,我找到了一个可以追溯到java.lang.ClassCastException: org.ksoap2.serialization.SoapObject

中的“misco”的解决方案

我不再尝试转换响应,而是自己手动构建List:

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);
    }
} 

答案 1 :(得分:1)

这是我的解决方案。这个对我有用。而不是使用Vector,获取SoapObject响应的值。

               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
                }

答案 2 :(得分:0)

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");  
        }