我现在正忙着从我的回复中获取一个复杂类型(列表)三天,但总是得到一个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看起来是一样的:
* <complexType name="responsiblePartyFacade">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="discriminator" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="admin" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
* <element name="children" type="{http://ws.my-url.com/}pairIntBoolFacade" maxOccurs="unbounded" minOccurs="0"/>
* <element name="plantcomponents" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </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
有人可以给我一个提示吗?
答案 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");
}