android - KSOAP2 处理复杂响应(向量)

标签 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 应用程序。

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

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

到目前为止,一切都很好。

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

责任方获取响应

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

有人可以给我提示吗?

最佳答案

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

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

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

关于android - KSOAP2 处理复杂响应(向量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16494823/

相关文章:

android - 如何对长文本进行分页?

android - 我试图在对话框中添加评级栏,但我在星数方面遇到了一些问题

android - Google Firebase 序列化/反序列化

ios - 获取 BLE 设备的响应

java - Android-使用 putExtra(String name, String value) 方法时出错

c++ - 将 C++ std::vector<std::string> 转换为 std::vector<unsigned char> (反之亦然)

c++ - 无法将 vector<int> 转换为 int* 用于 bool testPIN

vector - 在 Rust 枚举/结构中接受 slice 和 Vec

http - Haskell SimpleHTTP 获取响应代码

java - "request"和 "response"变量或值是在 Java EE 中预定义的吗?