Consumiendo Web Services con kSoap

ksoap

En este tutorial, aprenderás a consumir servicios web utilizando la popular librería kSoap en una aplicación Android. kSoap es una librería respetable y admirada por desarrolladores que tienen necesidad de analizar mensajes WSDL (Web Service Description Language) y SOAP (Simple Object Access Protocol).

Introducción.

kSOAP es una librería tipo cliente SOAP elegante, ligera y eficiente. La biblioteca es de código abierto, fácil de usar, y puede salvarlo de la molestia de la codificación de un analizador personalizado. Es una de las bibliotecas de SOAP más fiables disponibles en la actualidad y se actualiza con frecuencia, lo cual es una buena señal para un proyecto de código abierto.

A menudo es arriesgado para integrar el software de código abierto (OSS) en un proyecto, ya que puede causar problemas imprevistos en el camino. Busque siempre los comentarios y opiniones de otros desarrolladores que han utilizado la biblioteca. Si el proyecto no está en desarrollo activo, puede ser mejor buscar una solución alternativa.

El objetivo de este tutorial es para que se familiarice con la biblioteca kSOAP. Para fines de demostración, vamos a utilizar un servicio web simple de W3Schools. El servicio web es un convertidor de Fahrenheit a Celsius. El servicio web acepta un valor en grados Fahrenheit y responde con el valor equivalente en grados Celsius.

  1. Primeros Pasos.Paso 1: Configuración del proyecto.

    El archivo manifiesto del proyecto, necesitaras especificar que la aplicación tenga permisos para conectarse a Internet. También especificaremos las versiones del SDK, tanto objetivo como mínima. Echa un vistazo al archivo de manifiesto que se muestra a continuación.

    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    Paso 2: Descargar kSoap.

    Siempre trata de utilizar el ultimo lanzamiento estable de la librería o actualiza la librería si la usas en una aplicación cuando una actualización se libere. Es una buena practica para mantener las dependencias de una proyecto arriba por varias razones, como la seguridad o soluciones a errores. En este tutorial, usaremos la versión 3.x de la librería kSoap, que puedes encontrar en la pagina de descargas del proyecto. Después de descargar la librería kSoap, agrégala a tu carpeta «libs» en el proyecto.

    Paso 3: Agregar kSoap a tu proyecto.

    Para utilizar la biblioteca kSOAP en su proyecto, tendrá que agregarlo a su proyecto. Te mostrare como agregar usando Eclipse. Da clic derecho sobre tu proyecto y selecciona «Build Path -> Configura  Build Path…«, clic sobre la sección Java Build Path, abre la pestaña «Libraries» y presiona sobre el boton «Add Jars…» y hasta la carpeta «libs» donde se encuentra el archivo kSoap y acepta. Una vez hecho eso, selecciona la pestaña «Order and Export» y activamos la casilla de la librería kSoap. Aquí dejo imágenes para clarificar los pasos:

    AndroidBuildPath

    AgregarLibreria

    KSoapLibs

    kSoapExport&Order

  2. W3Schools Web Service.

    El uso de la biblioteca kSOAP para consumir un servicio web implica una serie de pasos. Sin embargo, antes de sumergirse de cabeza en el uso de la biblioteca kSOAP, es útil para contarles un poco más sobre el servicio web que vamos a utilizar.Visite el sitio web del servicio web de W3Schools que utilizaremos en este tutorial. Verás que hay dos operaciones, CelsiusToFahrenheit y FahrenheitToCelsius. El nombre de cada operación se explica por sí mismo. El URL del servicio Web es el URL base que vamos a utilizar para conectar con el servicio web.Si selecciona una operación en la página web de W3Schools, te muestra un ejemplo de la solicitud que el servicio web espera, así como la respuesta del servicio web. Echa un vistazo a el siguiente fragmento de código, que es un ejemplo de petición que el servicio web espera. Preste mucha atención al SOAPAction en el fragmento de código ya que lo vamos a utilizar un poco más adelante en este tutorial.

    POST /webservices/tempconvert.asmx HTTP/1.1
    Host: www.w3schools.com
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    SOAPAction: "http://www.w3schools.com/webservices/FahrenheitToCelsius"
    <!--?xml version="1.0" encoding="utf-8"?-->
    string

    El siguiente fragmento de código muestra un ejemplo de respuesta del servicio web.

    HTTP/1.1 200 OK
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    <!--?xml version="1.0" encoding="utf-8"?-->
    string

  3. Usando kSoap

    Paso 1. Crear un envoltorio.

    La primera cosa que necesitaremos hacer es crear un envoltorio SOAP usando la clase SoapSerializationEnvelope (org.ksoap2.serialization.SoarpSerializationEnvelope), que necesitaremos importar de la librería kSoap. Echa un vistazo al fragmento de código que esta abajo, en el cual tengo una estancia iniciada de la clase SoapSerializationEnvelope.

    SoapSerializationEnvelope envelope = getSoapSerializationEnvelope(request);

    El método getSoapSerializationEnvelope no esta definido en la librería kSoap. Es un método de ayuda que he creado para trabajar con la librería un poco mas fácil. El método regresa el envoltorio SOAP que necesitares para el resto del ejemplo. Echa un vistazo de su implementación debajo.

    private final SoapSerializationEnvelope getSoapSerializationEnvelope(SoapObject request) {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.implicitTypes = true;
        envelope.setAddAdornments(false);
        envelope.setOutputSoapObject(request);

        return envelope;
    }

    El método getSoapSerializationEnvelope acepta una instancia SoapObject, que es la petición. Veremos como crear la petición en unos minutos. Cuando creamos la instancia de la clase SoapSerializationEnvelope, la versión SoapEnvelope se establece en SoapEnvelope.VER11, el cual le dice a la librería kSoap que estaremos utilizando SOAP 1.1. Nosotros establecemos la propiedad del envoltorio dotNet como true para indicar que el servicio web que consumiremos se ejecuta bajo Microsoft .NET Framework.

    envelope.dotNet = true;

    Paso 2: Configurando el envoltorio.

    Es tiempo ahora de configurar el envoltorio SOAP mediante el establecimiento de la solicitud de información. Comienza importando la clase Soap Object (org.ksoap2.serialization.SoapObject) y echa un vistazo al fragmento de código que se encuentra abajo para ver como configurar el envoltorio. Empezaremos a crear una instancia de la clase SoapObject, que requiere de dos parámetros, un namespace y un nombre de método. Puedes agregar propiedades adicionales para solicitar mediante el método addProperty como se muestra debajo. En nuestro ejemplo, utilizo addProperty para agregar el valor de grados Fahrenheit a la solicitud.

    String methodname = "FahrenheitToCelsius";
    SoapObject request = new SoapObject(NAMESPACE, methodname);
    request.addProperty("Fahrenheit", fValue);

    Tu estarás preguntándote de donde proviene el NAMESPACE. Es una cadena de caracteres (String) privada y estática que se define en cualquier lugar de la aplicación como puedes ver debajo.

    private static final String NAMESPACE = "http://www.w3schools.com/webservices/";

    Paso 3: Creando la petición.

    Para enviar la petición al servicio web, necesitaremos crear una solicitud de transporte HTTP. Usaremos la clase HttpTransportSE (org.ksoap2.transport.HttpTransportSE) para esto. Echa un vistazo al ejemplo debajo.

    HttpTransportSE ht = getHttpTransportSE();

    Como te estarás suponiendo, getHttpTransportSE es otro método de ayuda y te permite crear rápidamente un objeto de transporte HTTP. Eso hará menos tedioso crear un objeto de transporte cada vez que quieras realizar una llamada al servicio web. Echa un vistazo a su implementación debajo. Para crear una instancia HttpTransportSE, nosotros únicamente  necesitaremos la URL del servicio web, el cual es otro String estático y privado como puede ver debajo.

    private final HttpTransportSE getHttpTransportSE() {
        HttpTransportSE ht = new HttpTransportSE(Proxy.NO_PROXY,MAIN_REQUEST_URL,60000);
        ht.debug = true;
        ht.setXmlVersionTag("<!--?xml version=\"1.0\" encoding= \"UTF-8\" ?-->");
        return ht;
    }

    private static final String MAIN_REQUEST_URL = "http://www.w3schools.com/webservices/tempconvert.asmx";

    En getHttpTransportSE, nosotros también configuramos el objeto HttpTransportSE. Con Proxy.NO_PROXY como primer argumento del constructor, especificamos que ningún proxy es utilizado para la petición. El tercer argumento del constructor establece el tiempo de espera de sesión en mili segundos. Para hacer mas fácil la depuración, establecemos la propiedad debug del objecto a true. Cualquier inconveniente aparecerá registrado en LogCat.

    Paso 4: Enviando la petición.

    Es tiempo de enviar la solicitud SOAP al servicio web. Lo haremos sobre HTTP utilizando los objectos de transporte y envoltura que hemos creado antes. El objecto de transporte HTTP tiene un método de llamada (call), el cual es usado para agregar la instancia de SoapAction y el envoltorio que hemos creado antes.

    ht.call(SOAP_ACTION, envelope);

    SOAP_ACTION es otro String estático privado como puedes ver debajo.

    private static final String SOAP_ACTION = "http://www.w3schools.com/webservices/FahrenheitToCelsius";

    Paso 5: Procesando la respuesta.

    Cuando el servicio web envía de regreso una respuesta, necesitamos procesarla y manejar cualquier error que pueda ocurrir. Podemos entonces mostrar los datos al usuario. Mira al fragmento de código mas abajo en el cual extrajimos la respuesta del envoltorio respuesta usando el método getRespond.

    SoapPrimitive resultsString = (SoapPrimitive)envelope.getResponse();

    Estoy usando un tipo SoapPrimitive, pero también puedes  utilizar una instancia SoapObject si la respuesta del servicio web es XML. Puedes  utilizar la instancia SoapObject para obtener los valores de la respuesta y almacenarlos en un array. Llamar a toString en el objecto SoapPrimitive para convertir la respuesta en una simple cadena de caracteres que puedes utilizar en tu aplicación.

    Echa un vistazo al siguiente fragmento de código en el cual he implementado un método: getCelsiusConversion. El método acepta una variable de cadena de caracteres como único argumento. La variable es agregada como una propiedad para la petición SOAP como vimos anteriormente en este tutorial. El método consume el valor proporcionado en grados Fahrenheit. Este valor es enviado y procesado por el servicio web y regresa una respuesta en grados Celsius.

    public String getCelsiusConversion(String fValue) {
            String data = null;
            String methodname = "FahrenheitToCelsius";

            SoapObject request = new SoapObject(NAMESPACE, methodname);
            request.addProperty("Fahrenheit", fValue);

            SoapSerializationEnvelope envelope = getSoapSerializationEnvelope(request);

            HttpTransportSE ht = getHttpTransportSE();
            try {
                ht.call(SOAP_ACTION, envelope);
                testHttpResponse(ht);
                SoapPrimitive resultsString = (SoapPrimitive)envelope.getResponse();

                List COOKIE_HEADER = (List)      ht.getServiceConnection().getResponseProperties();

                for (int i = 0; i < COOKIE_HEADER.size(); i++) {
                    String key = COOKIE_HEADER.get(i).getKey();
                    String value = COOKIE_HEADER.get(i).getValue();

                    if (key != null && key.equalsIgnoreCase("set-cookie")) {
                        SoapRequests.SESSION_ID = value.trim();
                        Log.v("SOAP RETURN", "Cookie :" + SoapRequests.SESSION_ID);
                        break;
                    }
                }
                data = resultsString.toString();

            } catch (SocketTimeoutException t) {
                t.printStackTrace();
            } catch (IOException i) {
                i.printStackTrace();
            } catch (Exception q) {
                q.printStackTrace();
            }
       return data;
    }

    Use dos String en getCelsiusConversion: data y methodname. La variable data sera retornada por el método después de que el servicio web envié de vuelta una respuesta, mientras methodname almacena el nombre de la operación del servicio web que se ejecutara y es usado en la instancia SoapObject.

    Habrás notado el ciclo for en getCelsiusConversion, el cual no es parte de los pasos que hemos visto anteriormente. Cuando trabajamos con servicios web mas complejos, es importante mantener una ruta de la sesión actual. En el fragmento de abajo, guarde la sesión y la mantuve a la vista para cada ocasión en que llame  al servicio web.

    for (int i = 0; i < COOKIE_HEADER.size(); i++) {
        String key = COOKIE_HEADER.get(i).getKey();
        String value = COOKIE_HEADER.get(i).getValue();
        if (key != null && key.equalsIgnoreCase("set-cookie")) {
            SoapRequests.SESSION_ID = value.trim();
            Log.v("SOAP RETURN", "Cookie :" + SoapRequests.SESSION_ID);
            break;
        }
    }

  4. Creando la interfaz de usuario.Ahora que el trabajo duro está hecho, es el momento de hacer uso de lo que acabamos de crear. Para finalizar este tutorial, te mostraré cómo crear una interfaz de usuario sencilla para la conversión de un valor en grados Fahrenheit a un valor en grados Celsius y mostrar el resultado en el dispositivo del usuario.Paso 1: Crear el diseño.Primero, necesitamos crear un archivo XML en la carpeta «layout«. Echa un vistazo al fragmente debajo. Es una simple ilustración de una interfaz de usuario creada en XML.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" />
    <EditText
     android:layout_width="200dp"
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal"
     android:hint="Fahrenheit"
     android:inputType="number"
     android:id="@+id/value_to_convert" />

    <Button
     android:layout_width="200dp"
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal"
     android:text="Convert to Celsius"
     android:id="@+id/convert" />

    <TextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:gravity="center_horizontal"
     android:textSize="30dp"
     android:id="@+id/answer" />
    </LinearLayout>

    Creamos tres componentes: un EditText, un Button y un TextView. El EditText es utilizado para captura el valor que intentaremos enviar al servicio web. El Button es usa para ejecutar el hilo que invocara getCelsiusConversion y el TextView mostrara la respuesta obtenida desde el servicio web.

    Paso 2: Crear la actividad.
    el siguiente paso  es crear una instancia de Activity para mostrar el diseño que hemos creado. Mira el siguiente fragmento de código. Esto no te  sorprendera si has  desarrollado aplicaciones Android antes.

    package com.example.KsoapExample;

    import android.app.Activity;
    import android.os.Bundle;

    public class MyActivity extends Activity {
        /**
        * Called when the activity is first created.
        */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    }

    Ahora que nos hemos ocupado de la interfaz de  usuario, podemos atar todo junto. Mira el siguiente fragmento para ver como esta hecho.

    package com.example.KsoapExample;

    import android.app.Activity;
    import android.os.Bundle;

    public class MyActivity extends Activity {
        private TextView txt;
        private String celsius;
        /**
         * Called when the activity is first created.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            final EditText edt = (EditText)findViewById(R.id.value_to_convert);
            Button btn = (Button)findViewById(R.id.convert);
            txt = (TextView)findViewById(R.id.answer);

            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (edt.length() > 0) {
                        getCelsius(edt.getText().toString());
                    } else {
                        txt.setText("Fahrenheit value can not be empty.");
                    }
                }
            });
        }
    }

    En onCreate, hemos  establecido un oyente al botón, btn. También verifica que un valor se ha introducido en el campo antes de llamar  al servicio web. En el oyente clic del botón, el valor pasado a getCelsius es convertido a un String porque el servicio web espera un valor String. La implementación de getCelsius no es muy difícil como podrás ver debajo.

    private final void getCelsius(final String toConvert) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                SoapRequests ex = new SoapRequests();
                celsius = ex.getCelsiusConversion(toConvert);
                handler.sendEmptyMessage(0);
                }
        }).start();
    }

    En getCelsius, un nuevo hilo es creado, el cual correrá y creara la instancia de la clase que implementa getCelsiusConversion. Cuando recibimos una respuesta del servicio web, enviamos un mensaje al controlador dedicado a actualizar la interfaz de usuario para que muestre el valor en grados centígrados.

    public Handler handler = new Handler(new Handler.Callback() {

        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {

                case 0:
                    txt.setText(celsius);
                    break;
            }
            return false;
        }
    });

    En el controlador, actualizamos la instancia TextView con el valor que nosotros recibimos del servicio web. Mira el resultado final debajo.

    finalkSoap

Conclusión.

Yo ahora debes ser capaz de agregar la librería kSoap a un proyecto y aprovechar para hacer peticiones a un servicio web que utilice el protocolo SOAP. Trabajar con la librería kSoap sera mas fácil con un poco de practica  y los animo a intentar crear el servicio web de Celsius a Fahrenheit. Puedes usar nuestro ejemplo de aplicación Android que es parte del tutorial como un pequeño extra de ayuda.

—-

Entrada original: http://code.tutsplus.com/tutorials/consuming-web-services-with-ksoap–mobile-21242

—-

Articulo traducido porque es el mas reciente y sencillo que he leído de esta librería, aunque esta claro que no es la primera vez que hablan de ella por lo que les dejo otros enlaces de interés:

Curso Android en Español SGOliver – kSoap Parte 1
Curso Android en Español SGOliver – kSoap Parte 2

kSoap – Otra implementación sencilla y con clases (Ingles)
KSoap – Manejo de servicios web que responden arrays de objectos (Ingles)

To-Do: Agregar el ejemplo de este articulo para su descarga.  Código de ejemplo: http://1drv.ms/1UT5AQd

2 comentarios en “Consumiendo Web Services con kSoap”

Deja un comentario