plusone

12. September 2011

WebService mit StringArray - Part 3

Nabend,

die Suchbegriffe für Android WebService stellen alle meine anderen Beiträge in den Schatten. Deswegen will ich euch heute zeigen, wie man String[] als Parameter beim Aufruf vom WebService mit einem AndroidClient mit der Hilfe der Ableitung von Vector<String> und Implementierung von KvmSerializable.

Soviel zu langen Sätzen nun zum Part drei meines "Android und WebService"-Tutorial und dem Code.
Ich habe bereits in meinem Beitrag über AndroidWebServiceClient bereits gezeigt, wie ihr eine einfache Verbindung zum WebService herstellen könnt. Jetzt verändern wir den Parameter zum StringArray.
Solltet ihr einfach nach gleichem Prinzip ein Array also ein Object[] oder eins der primitiven Datentypen rüberreichen (int[]), werdet ihr schnell eine Exception bekommen, wie diese hier:
Caused by: java.lang.RuntimeException: Cannot serialize: [Ljava.lang.String;@46107820
at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:629)

Ein String implementiert zwar Serializable, aber ein String[] wird anders gehandhabt. Es wird die Einbindung der Schnittstelle KvmSerializable benötigt.
Deswegen habe ich mir eine kleine Klasse zusammen gebaut, diese wandelt meine String[] als Parameter zu einem Object womit KSOAP2 arbeiten und damit eine erfolgreiche übergabe zum Webservice erstellt werden kann.


import java.util.Hashtable;
import java.util.Vector;


import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;


public class StringArray extends Vector<String> implements KvmSerializable {


    /**
     *
     */
    private static final long serialVersionUID = 1L;


    /**
     * Kontruktor - erleichtert das einfügen des StringArray
     *
     * @param channelsArray
     */
    public StringArray(String[] stringArray) {
        addAll(stringArray);
    }


    @Override
    public Object getProperty(int arg0) {
        return this.get(arg0);
    }


    @Override
    public int getPropertyCount() {
        return this.size();
    }


    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo info) {
        info.name = "string";
        info.type = PropertyInfo.VECTOR_CLASS;
    }


    @Override
    public void setProperty(int arg0, Object arg1) {
        this.add(arg1.toString());


    }


    /**
     * Hilfsklasse - fügt alle Strings des Arrays dem Vector zu
     *
     * @param stringArray
     */
    public synchronized void addAll(String[] stringArray) {
        for (int i = 0; i < stringArray.length; i++) {
            add(stringArray[i]);
        }
    }
}
Das ist der Code der Klasse. Der größte Teil erklärt sich von selbst, ihr könnt ja englisch, nicht wahr? Fragt ruhig :)

Das Interessante erklär ich.
Die Methode getPropertyInfo(...) wird vom WebService zum Verständniss aufgerufen. Der PropertyInfo, die mit CallByReference benutzt wird, sagen wir, dass das Element ein String ist (Groß- und Kleinschreibung spielt hier wohl keine Rolle) und das es nicht nur einer ist, sonder direkt ein Vector. Vector steht für eine Ansammlung, vergleichbar mit ArrayList haben ja schließlich die selber Mutterklasse.

@Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo info) {
        info.name = "string";
        info.type = PropertyInfo.VECTOR_CLASS;
    } 



So unser StringArray-Objekt ist fertig, aber wie wenden wir es richtig an?


Meine Methode des WebServices heißt EchoArray und erwartet ein Array aus Strings, was mir wieder zurück gegeben wird.
Für unbekannte variablen, bitte schauen meinen Teil 2b an. Diese Erklärung baut darauf auf!
Der Unterschied im WebService besteht jetzt darin, dass es ein dotNet-WebService ist. Erkennbar beim Aufruf am envelope.dotNet = true;.
    public static void EchoArray(String[] stringArray) {
        String METHOD_NAME = "EchoArray";
        String SOAP_ACTION = NAMESPACE + "/" + METHOD_NAME;
        final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;
        final SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

         StringArray stringArrayObject = new StringArray(
stringArray);

        request.addProperty("
StringArray", stringArrayObject
);

        envelope.setOutputSoapObject(request);
        Object object = getResult(SOAP_ACTION, envelope);
}

Zur Erklärung:

new StringArray(stringArray)
Hier verwende ich meine Kontruktor, der gleichzeitig mein String[]-Argument zum Objekt "umwandelt", womit der WebService was anzufangen weiß.

request.addProperty("StringArray", stringArrayObject);
Diese Zeile benutzt nicht mehr den String[]-Argument sondern unsere StringArray-Klasse.

Mehr müsst ihr bei euren aufrufen des WebServices nicht ändern!

Schreibt ihr einmal diese Klasse, wird die Benutzung von String[] ein Leichtes. Da stimmt ihr mir bestimmt alle zu, wah?

Ich wünsch euch viel Erfolg.

regards
Alexander Fink

Keine Kommentare:

Kommentar veröffentlichen