Android y WCF REST

image

Este es un ejemplo sobre como conectar una aplicación Android a una servicio WCF REST

El servicio WCF está hosteado en un IIS bajo el nombre de notescenter (para este post) y el cliente desarrollado en Android consume dicho servicio.

El Servicio WCF

Nuestro servicio es muy simple y lo vamos a crear con el template “WCF REST Service Template 40(CS)” ya que el objetivo del ejemplo es mostrar como acceder desde la aplicación Android.

Dicho servicio mantiene una lista de notas en un repositorio en el servidor, si escribimos notescenter.neluz.int/note/help nos va a mostrar las acciones referente al servicio de notas:

image

donde cada acción, siguiendo los principios REST, significa:

  • Acciones sobre http://notecenter.neluz.int/note/
    • GET: obtiene la lista de notas.
    • POST: crea una nueva nota (el contenido se envía en el cuerpo del mensaje).
  • Acciones sobre http://notecenter.neluz.int/note/[id]
    • GET: obtiene la nota cuyo id es [id].
    • PUT: actualiza la nota cuyo id es [id] (el contenido se envía en el cuerpo del mensaje).
    • DELETE: elimina la nota cuyo id es [id]

El código completo del servicio se lo pueden bajar hacienco click aquí.

El cliente Android

Esta aplicación cuenta con 2 layout, uno que nos permite ingresar nuevas notas y otra que lista las notas existentes donde, si seleccionamos una nota la elimina. No hay confirmaciones ni detalles de presentación ya que no es el objetivo del post.

Android-1 Screenshot2

crear una nueva nota

listado de notas

La aplicación va a necesitar permisos de acceso a internet:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Mientras que la clase que se encarga de la comunicación Http con nuestro servicio WCF hace uso de los objetos HttpGet, HttpPost y HttpDelete. En el caso del POST podemos ver como son serealizados los datos como JSON.

El código es el siguiente:

package com.neluz.messageClient;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
 
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
 
public class HttpNote {
 
       public static String doGet(String path) throws URISyntaxException, IOException, ClientProtocolException {
               BufferedReader in = null;
               try {
                       HttpClient client = new DefaultHttpClient();
                       HttpGet request = new HttpGet();
                       request.setURI(new URI(path));
                       HttpResponse response = client.execute(request);
 
                       in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
 
                       StringBuffer sb = new StringBuffer("");
                       String line = "";
                       String NL = System.getProperty("line.separator");
                       while ((line = in.readLine()) != null) {
                               sb.append(line + NL);
                       }
                       in.close();
                       String array = sb.toString();
                       return array;
               } finally {
                       if (in != null) {
                               try {
                                       in.close();
                               } catch (IOException e) {
                                       e.printStackTrace();
                               }
                       }
               }
       }
 
       public static String doPost(String path, String text) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
               HttpPost httpost = new HttpPost(new URI(path));
               httpost.setHeader("Accept", "application/json");
               httpost.setHeader("Content-type", "application/json; charset=utf-8");
 
               JSONObject holder = new JSONObject();
               holder.put("Text", text);
 
               StringEntity se = new StringEntity(holder.toString());
 
               httpost.setEntity(se);
 
               DefaultHttpClient httpclient = new DefaultHttpClient();
               HttpResponse response = httpclient.execute(httpost);
 
               StringBuffer sb = new StringBuffer();
 
               BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
 
               String line;
               String NL = System.getProperty("line.separator");
               while ((line = in.readLine()) != null) {
                       sb.append(line + NL);
               }
               in.close();
               return sb.toString();
       }
 
       public static boolean doDelete(String path, int id) throws ClientProtocolException, IOException {
               StringBuilder url = new StringBuilder();
               url.append(path).append(id);
 
               HttpDelete httpdelete = new HttpDelete(url.toString());
 
               DefaultHttpClient httpclient = new DefaultHttpClient();
               HttpResponse response = httpclient.execute(httpdelete);
 
               StatusLine statusLine = response.getStatusLine();
 
               return statusLine.getStatusCode() == 200;
       }
}

y para deserealizar el contenido de los mensajes recibidos usaremos:

package com.neluz.messageClient;
 
import java.util.ArrayList;
import java.util.List;
 
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
public class JsonNote {
       public static List<Note> transformJSON2Notes(String response) throws JSONException {
               List<Note> result = new ArrayList<Note>();
 
               JSONArray notes = new JSONArray(response);
               for (int i = 0; i < notes.length(); i++) {
                       JSONObject note = notes.getJSONObject(i);
                       Note n = transformJSON2Note(note);
                       result.add(n);
               }
               return result;
       }
 
       public static Note transformJSON2Note(String note) throws JSONException {
               JSONObject n = new JSONObject(note);
               return transformJSON2Note(n);
       }
 
       private static Note transformJSON2Note(JSONObject note) throws JSONException {
               Note n = new Note();
               n.setId(note.getInt("Id"));
               n.setText(note.getString("Text"));
               return n;
       }
}

el código completo del cliente lo pueden descargar haciendo click aquí.

Nota: estoy trabajando con la versión 7 del API de Android y tuve problemas con la URL, si pongo “http://notecenter.neluz.int/note” al hacer el POST me termina ejecutando el GET, esto se debe a que el IIS cuando recibe la url “http://notecenter.neluz.int/note” devuelve en 307 (Redirect) y el componente de Android hace un GET a la dirección indicada, es decir a “http://notecenter.neluz.int/note/”. Si directamente ponemos “notecenter.neluz.int/note/” en la url del POST funciona perfectamente (notese la diferencia en la / final).

3 comentarios:

  1. Hola, desde la aplicación cliente de android me da error al acceder a http://localhost:52743/Note/, en cambio, en la aplicación de consola que incluye la solución del servicio REST, funciona correctamente (y accesiendo por el navegador), ¿que estoy haciendo mal?

    Un saludo.

    ResponderBorrar
    Respuestas
    1. ¿que error te da?... puede ser que, por ejemplo, no tengas en la misma red el dispositivo android y el servicio wcf.

      Borrar
  2. Directamente no encuentra el host, he leido por ahí que se debe a que no encuentra las peticiones al localhost del servidor de desarrollo, hay que configurarlo para que ataque a una dns fuera de la red, aunque de todos modos mi hosting falla al intentar acceder al servicio rest, me dá problemas de permisos, pero eso es otro tema...

    Gracias por la respuesta y por el post.
    Un saludo.

    ResponderBorrar