我知道一些关于ksoap请求的基础知识,如果它很简单,我可以做到没问题。但我不知道如何发出一个请求将解析为看起来像这样的请求转储:
<Organizer xsi:type="tns:Person"><name xsi:type="xsd:string">hisname</name>
<lastname xsi:type="xsd:string">hislast</lastname>
人的定义如下:
<xsd:complexType name="Person"><xsd:all>
<xsd:element name="name" type="xsd:string" nillable="true"/>
<xsd:element name="lastname" type="xsd:string" nillable="true"/>
</xsd:all></xsd:complexType>
之后我需要发送一组人员。它应该看起来像
<guests xsi:type="soap-enc:Array" soap-enc:arrayType="tns:Person[1]">
<item xsi:type="tns:Person">
<name xsi:type="xsd:string">mitja</name>
<lastname xsi:type="xsd:string">last</lastname>
</item></guests>
任何想法怎么做?
答案 0 :(得分:0)
使用KSoap2处理数组可能会非常棘手,并且会以不同的方式执行,具体取决于您使用的KSoap2的版本。在我们的例子中,我们定义了可扩展的SoapObject(ExtendedSoapObject),它在用作请求DTO时接受数组字段作为属性,并在用作响应DTO时克服了数组处理问题。
我们为Android和J2ME版本的Ksoap2定义了不同版本的ExtendedSoapObject对象。
这是Android版本:
/**
* Clase que extiende la funcionalidad de SoapObject para poder establecer
* propiedades de tipo array dado que la implementación de KSoap2 tiene la
* limitación de tratar los objetos de un array como múltiples propiedades con
* el mismo nombre. Pero si intentamos recuperar la propiedad en cuestión a
* partir del nombre sólo nos devuelve la primera instancia.
*
* @author BIFMP
*/
public class ExtendedSoapObject extends SoapObject
{
/**
* Crea una instancia de {@link ExtendedSoapObject}
*
* @param namespace
* namespace del objeto
* @param name
* nombre del objeto
*/
public ExtendedSoapObject(String namespace, String name)
{
super(namespace, name);
}
/**
* Crea una instancia de {@link ExtendedSoapObject} a partir de una
* instancia de la clase base.
*
* @param o
* instancia de {@link SoapObject}
*/
public ExtendedSoapObject(SoapObject o)
{
super(o.getNamespace(), o.getName());
for (int i = 0; i < o.getAttributeCount(); i++)
{
AttributeInfo ai = new AttributeInfo();
o.getAttributeInfo(i, ai);
ai.setValue(o.getAttribute(i));
addAttribute(ai);
}
for (int i = 0; i < o.getPropertyCount(); i++)
{
PropertyInfo pi = new PropertyInfo();
o.getPropertyInfo(i, pi);
pi.setValue(o.getProperty(i));
addProperty(pi);
}
}
/**
* Permite pasar objetos de tipo array.
*/
@Override
public SoapObject addProperty(String name, Object value)
{
if (value instanceof Object[])
{
Object[] subValues = (Object[]) value;
for (int i = 0; i < subValues.length; i++)
{
super.addProperty(name, subValues[i]);
}
}
else
{
super.addProperty(name, value);
}
return this;
}
/**
* Este método devuelve un objeto {@link SoapObject} o valor primitivo
* {@link SoapPrimitive} o un array de los mismos. Puede devolver null si es
* el valor que tiene la propiedad (porque fue lo que devolvió el método
* remoto) o si no se encuentra la propiedad.
*/
@Override
public Object getProperty(String name)
{
List<Object> result = new ArrayList<Object>();
for (int i = 0; i < properties.size(); i++)
{
PropertyInfo prop = (PropertyInfo) properties.elementAt(i);
if (prop.getName() != null && prop.getName().equals(name))
{
result.add(unwrap(prop));
}
}
if (result.size() == 1)
{
return result.get(0);
}
else if (result.size() > 1)
{
return result.toArray(new Object[0]);
}
else
{
return null;
}
}
/**
* Este método siempre devuelve un array de objetos.
*
* @param name
* @return
*/
public Object[] getArrayProperty(String name)
{
Object o = getProperty(name);
Object values[] = null;
if (o != null)
{
if (o instanceof Object[])
{
values = (Object[]) o;
}
else
{
values = new Object[1];
values[0] = o;
}
}
return values;
}
Object unwrap(Object o)
{
if (o instanceof PropertyInfo)
{
return unwrap(((PropertyInfo) o).getValue());
}
else if (o instanceof SoapPrimitive || o instanceof SoapObject)
{
return o;
}
return null;
}
}
和J2ME版本:
/**
* Clase que extiende la funcionalidad de SoapObject para poder establecer
* propiedades de tipo array dado que la implementación de KSoap2 tiene la
* limitación de tratar los objetos de un array como múltiples propiedades con
* el mismo nombre. Pero si intentamos recuperar la propiedad en cuestión a
* partir del nombre sólo nos devuelve la primera instancia.
*
* @author BIFMP
*/
public class ExtendedSoapObject extends SoapObject
{
/**
* Crea una instancia de {@link ExtendedSoapObject}
*
* @param namespace
* namespace del objeto
* @param name
* nombre del objeto
*/
public ExtendedSoapObject(String namespace, String name)
{
super(namespace, name);
}
/**
* Crea una instancia de {@link ExtendedSoapObject} a partir de una
* instancia de la clase base.
*
* @param o
* instancia de {@link SoapObject}
*/
public ExtendedSoapObject(SoapObject o)
{
super(o.getNamespace(), o.getName());
for (int i = 0; i < o.getPropertyCount(); i++)
{
PropertyInfo pi = new PropertyInfo();
o.getPropertyInfo(i, null, pi);
addProperty(pi, o.getProperty(i));
}
}
/**
* Permite pasar objetos de tipo array.
*/
public SoapObject addProperty(String name, Object value)
{
if (value instanceof Object[])
{
Object[] subValues = (Object[]) value;
for (int i = 0; i < subValues.length; i++)
{
super.addProperty(name, subValues[i]);
}
}
else
{
super.addProperty(name, value);
}
return this;
}
/**
* Este método devuelve un objeto {@link SoapObject} o valor primitivo
* {@link SoapPrimitive} o un array de los mismos. Puede devolver null si es
* el valor que tiene la propiedad (porque fue lo que devolvió el método
* remoto) o si no se encuentra la propiedad.
*/
public Object getProperty(String name)
{
Vector result = new Vector();
PropertyInfo info = new PropertyInfo();
for (int i = 0; i < getPropertyCount(); i++)
{
getPropertyInfo(i, null, info);
if (info.name != null && info.name.equals(name))
{
result.addElement(getProperty(i));
}
}
if (result.size() == 1)
{
return result.elementAt(0);
}
else if (result.size() > 1)
{
Object resultArray[] = new Object[result.size()];
result.copyInto(resultArray);
return resultArray;
}
else
{
return null;
}
}
/**
* Este método siempre devuelve un array de objetos.
*
* @param name
* @return
*/
public Object[] getArrayProperty(String name)
{
Object o = getProperty(name);
Object values[] = null;
if (o != null)
{
if (o instanceof Object[])
{
values = (Object[]) o;
}
else
{
values = new Object[1];
values[0] = o;
}
}
return values;
}
}