0

我知道一些关于 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>

任何想法如何做到这一点?

4

1 回答 1

0

使用 KSoap2 处理数组可能很棘手,并且它以不同的方式执行,具体取决于您使用的 KSoap2 版本。在我们的案例中,我们定义了可扩展的 SoapObject (ExtendedSoapObject),它在用作请求 DTO 时接受数组字段作为属性,并在用作响应 DTO 时克服了数组处理问题。

我们为 Ksoap2 的 Android 和 J2ME 版本定义了不同版本的 ExtendedSoapObject 对象。

这是安卓版本:

/**
 * 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;
    }
}
于 2012-10-09T14:24:49.557 回答