2

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

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

我经常阅读几个链接页面/教程,以至于我几乎可以记住它们,包括这四个非常有用的页面:

还有更多,但我还是不明白:(

我希望我能给你所有你需要的输入来告诉我我的错误并给我一个修复它的提示。Web 服务已经在富客户端应用程序中成功实现,我现在必须使用相同的 Web 服务构建一个 android 应用程序。

我的第一步是处理“responsibleparty_get”-Response。

我的回复看起来像这样(限制为 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(来自富客户端)来看,责任方外观看起来是一样的:

 * &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>

到目前为止,很好。

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

责任方GetResponse

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 vector 不起作用)。

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

任何人都可以给我一个提示吗?

4

3 回答 3

3

在绝望的一天之后,我在 java.lang.ClassCastException 中找到了一个可以追溯到“misco”的灵魂:org.ksoap2.serialization.SoapObject

我不再尝试投射响应,而是自己手动构建列表:

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);
    }
} 
于 2013-05-12T17:34:49.947 回答
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
                }
于 2015-03-26T15:42:18.443 回答
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");  
        }           
于 2015-08-02T00:06:57.667 回答